├── .gitignore ├── examples ├── README ├── OSNoise1D │ └── OSNoise1D.pde └── OSNoise2D │ └── OSNoise2D.pde ├── lib ├── core.jar └── README ├── resources ├── code │ ├── ExampleTaglet.class │ ├── ant-contrib-1.0b3.jar │ └── ExampleTaglet.java ├── README.md ├── library.properties ├── build.properties ├── stylesheet.css └── build.xml ├── data └── README ├── .classpath ├── .project ├── README.md ├── license.txt ├── src └── algorithms │ └── noise │ ├── OpenSimplexNoise.java │ └── OpenSimplexNoiseKS.java └── web ├── stylesheet.css └── index.html /.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | tmp 3 | distribution 4 | -------------------------------------------------------------------------------- /examples/README: -------------------------------------------------------------------------------- 1 | add examples for your Library here. -------------------------------------------------------------------------------- /lib/core.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodingTrain/OpenSimplexNoise-for-Processing/HEAD/lib/core.jar -------------------------------------------------------------------------------- /resources/code/ExampleTaglet.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodingTrain/OpenSimplexNoise-for-Processing/HEAD/resources/code/ExampleTaglet.class -------------------------------------------------------------------------------- /resources/code/ant-contrib-1.0b3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodingTrain/OpenSimplexNoise-for-Processing/HEAD/resources/code/ant-contrib-1.0b3.jar -------------------------------------------------------------------------------- /data/README: -------------------------------------------------------------------------------- 1 | the data folder: 2 | If your Library is using files like images, sound files, 3 | any data file, etc., put them into the data folder. 4 | When coding your Library you can use processing's internal loading 5 | functions like loadImage(), loadStrings(), etc. to load files 6 | located inside the data folder into your Library. 7 | 8 | -------------------------------------------------------------------------------- /lib/README: -------------------------------------------------------------------------------- 1 | The lib folder: 2 | In case your Library requires 3rd party libraries, which need to be 3 | added to the distribution, put them into the lib folder. 4 | These 3rd party libraries will be added to your distribution and are 5 | located next to your Library's jar file. 6 | This does not apply to .jar files that are considered core processing libraries. -------------------------------------------------------------------------------- /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | opensimplexnoise-for-processing 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Noise Algorithm Library for Processing 2 | 3 | This repo is a work-in-progress library for additional noise algorithms in Processing. There are currently implementations for: 4 | 5 | * [x] Open Simplex Noise 6 | * [ ] Worley Noise 7 | * add your noise algorithm here! 8 | 9 | ## Tutorials 10 | 11 | This library was made for the video tutorial series "How to Make a Processing (Java) Library". 12 | 13 | * Part 1: https://youtu.be/pI2gvl9sdtE 14 | * Part 2: https://youtu.be/U0TGZCEWn8g 15 | 16 | ## API 17 | 18 | ```java 19 | 20 | // Create a noise object, optional 2nd argument for seed 21 | OpenSimplexNoise generator = new OpenSimplexNoise(this); 22 | 23 | // Get a noise value 24 | float xoff = 0.3; 25 | float val = generator.noise(xoff); 26 | ``` 27 | 28 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | A template to build a Library for the Processing programming environment. 2 | 3 | Part of the Processing project - http://processing.org 4 | 5 | Copyright 2011-2018 Elie Zananiri 6 | Copyright 2008-2011 Andreas Shlegel 7 | 8 | Licensed under the Apache License, Version 2.0 (the "License"); 9 | you may not use this file except in compliance with the License. 10 | You may obtain a copy of the License at 11 | 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | 14 | Unless required by applicable law or agreed to in writing, software 15 | distributed under the License is distributed on an "AS IS" BASIS, 16 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | See the License for the specific language governing permissions and 18 | limitations under the License. -------------------------------------------------------------------------------- /examples/OSNoise1D/OSNoise1D.pde: -------------------------------------------------------------------------------- 1 | import algorithms.noise.*; 2 | 3 | float xoff = 0.0; 4 | float xincrement = 0.01; 5 | 6 | OpenSimplexNoise osnoise; 7 | 8 | void setup() { 9 | size(640, 360); 10 | background(0); 11 | noStroke(); 12 | osnoise = new OpenSimplexNoise(); 13 | } 14 | 15 | void draw() { 16 | // Create an alpha blended background 17 | fill(0, 10); 18 | rect(0, 0, width, height); 19 | 20 | //float n = random(0,width); // Try this line instead of noise 21 | 22 | // Get a noise value based on xoff and scale it according to the window's width 23 | float n = osnoise.noise(xoff)*width; 24 | println(n); 25 | 26 | // With each cycle, increment xoff 27 | xoff += xincrement; 28 | 29 | // Draw the ellipse at the value produced by perlin noise 30 | fill(200); 31 | ellipse(n, height/2, 64, 64); 32 | } 33 | -------------------------------------------------------------------------------- /examples/OSNoise2D/OSNoise2D.pde: -------------------------------------------------------------------------------- 1 | import algorithms.noise.*; 2 | 3 | /** 4 | * Noise2D 5 | * by Daniel Shiffman. 6 | * 7 | * Using 2D noise to create simple texture. 8 | */ 9 | 10 | float increment = 0.02; 11 | OpenSimplexNoise osnoise; 12 | 13 | void setup() { 14 | size(640, 360); 15 | osnoise = new OpenSimplexNoise(); 16 | } 17 | 18 | void draw() { 19 | 20 | loadPixels(); 21 | 22 | float xoff = 0.0; // Start xoff at 0 23 | float detail = map(mouseX, 0, width, 0.1, 0.6); 24 | noiseDetail(8, detail); 25 | 26 | // For every x,y coordinate in a 2D space, calculate a noise value and produce a brightness value 27 | for (int x = 0; x < width; x++) { 28 | xoff += increment; // Increment xoff 29 | float yoff = 0.0; // For every xoff, start yoff at 0 30 | for (int y = 0; y < height; y++) { 31 | yoff += increment; // Increment yoff 32 | 33 | // Calculate noise and scale by 255 34 | float bright = osnoise.noise(xoff, yoff) * 255; 35 | 36 | // Try using this line instead 37 | //float bright = random(0,255); 38 | 39 | // Set each pixel onscreen to a grayscale value 40 | pixels[x+y*width] = color(bright); 41 | } 42 | } 43 | 44 | updatePixels(); 45 | } 46 | -------------------------------------------------------------------------------- /src/algorithms/noise/OpenSimplexNoise.java: -------------------------------------------------------------------------------- 1 | package algorithms.noise; 2 | 3 | 4 | /** 5 | * This is a template class and can be used to start a new processing Library. 6 | * Make sure you rename this class as well as the name of the example package 'template' 7 | * to your own Library naming convention. 8 | * 9 | * (the tag example followed by the name of an example included in folder 'examples' will 10 | * automatically include the example in the javadoc.) 11 | * 12 | * @example Hello 13 | */ 14 | public class OpenSimplexNoise { 15 | 16 | private OpenSimplexNoiseKS generator; 17 | 18 | public final static String VERSION = "##library.prettyVersion##"; 19 | 20 | 21 | /** 22 | * Constructs a new OpenSimplexNoise object, 23 | * using the system's current time as the noise seed. 24 | */ 25 | public OpenSimplexNoise() { 26 | this(System.currentTimeMillis()); 27 | } 28 | 29 | /** 30 | * Constructs a new OpenSimplexNoise object, 31 | * using the provided value as the noise seed. 32 | */ 33 | public OpenSimplexNoise(long seed) { 34 | welcome(); 35 | generator = new OpenSimplexNoiseKS(seed); 36 | } 37 | 38 | 39 | private void welcome() { 40 | System.out.println("##library.name## ##library.prettyVersion## by ##author##"); 41 | } 42 | 43 | private double remap(double val) { 44 | return (val + 1) * 0.5; 45 | } 46 | 47 | 48 | public float noise (float xoff) { 49 | return this.noise(xoff, 0); 50 | } 51 | 52 | public float noise (float xoff, float yoff) { 53 | return (float) remap(generator.eval(xoff, yoff)); 54 | } 55 | 56 | public float noise (float xoff, float yoff, float zoff) { 57 | return (float) remap(generator.eval(xoff, yoff, zoff)); 58 | } 59 | 60 | public float noise (float xoff, float yoff, float zoff, float uoff) { 61 | return (float) remap(generator.eval(xoff, yoff, zoff, uoff)); 62 | } 63 | 64 | 65 | /** 66 | * return the version of the Library. 67 | * 68 | * @return String 69 | */ 70 | public static String version() { 71 | return VERSION; 72 | } 73 | } 74 | 75 | -------------------------------------------------------------------------------- /resources/README.md: -------------------------------------------------------------------------------- 1 | ## How to install ##library.name## 2 | 3 | ### Install with the Contribution Manager 4 | 5 | Add contributed Libraries by selecting the menu item _Sketch_ → _Import Library..._ → _Add Library..._ This will open the Contribution Manager, where you can browse for ##library.name##, or any other Library you want to install. 6 | 7 | Not all available Libraries have been converted to show up in this menu. If a Library isn't there, it will need to be installed manually by following the instructions below. 8 | 9 | ### Manual Install 10 | 11 | Contributed Libraries may be downloaded separately and manually placed within the `libraries` folder of your Processing sketchbook. To find (and change) the Processing sketchbook location on your computer, open the Preferences window from the Processing application (PDE) and look for the "Sketchbook location" item at the top. 12 | 13 | By default the following locations are used for your sketchbook folder: 14 | * For Mac users, the sketchbook folder is located inside `~/Documents/Processing` 15 | * For Windows users, the sketchbook folder is located inside `My Documents/Processing` 16 | 17 | Download ##library.name## from ##library.url## 18 | 19 | Unzip and copy the contributed Library's folder into the `libraries` folder in the Processing sketchbook. You will need to create this `libraries` folder if it does not exist. 20 | 21 | The folder structure for Library ##library.name## should be as follows: 22 | 23 | ``` 24 | Processing 25 | libraries 26 | ##library.name## 27 | examples 28 | library 29 | ##library.name##.jar 30 | reference 31 | src 32 | ``` 33 | 34 | Some folders like `examples` or `src` might be missing. After Library ##library.name## has been successfully installed, restart the Processing application. 35 | 36 | ### Troubleshooting 37 | 38 | If you're having trouble, have a look at the [Processing Wiki](https://github.com/processing/processing/wiki/How-to-Install-a-Contributed-Library) for more information, or contact the author [##author.name##](##author.url##). 39 | -------------------------------------------------------------------------------- /web/stylesheet.css: -------------------------------------------------------------------------------- 1 | /* processingLibs style by andreas schlegel, sojamo. */ 2 | 3 | 4 | * { 5 | margin:0; 6 | padding:0; 7 | border:0; 8 | } 9 | 10 | 11 | body { 12 | font-family : Verdana, Geneva, Arial, Helvetica, sans-serif; 13 | font-size : 100%; 14 | font-size : 0.70em; 15 | font-weight : normal; 16 | line-height : normal; 17 | } 18 | 19 | 20 | 21 | #container { 22 | margin-left:64px; 23 | background-color:#fff; 24 | } 25 | 26 | #header { 27 | float:left; 28 | padding-top:24px; 29 | padding-bottom:48px; 30 | } 31 | 32 | #menu { 33 | margin-top:16px; 34 | float:left; 35 | margin-bottom:64px; 36 | } 37 | 38 | 39 | #about, 40 | #download, 41 | #examples, 42 | #demos, 43 | #misc { 44 | width:480px; 45 | float:left; 46 | margin-right:24px; 47 | } 48 | 49 | 50 | #resources, #info { 51 | width:320px; 52 | float:left; 53 | } 54 | 55 | 56 | .clear { 57 | clear:both; 58 | } 59 | 60 | #footer { 61 | margin-top:300px; 62 | height:20px; 63 | margin-bottom:32px; 64 | } 65 | 66 | 67 | ul { 68 | list-style:none; 69 | padding:0; 70 | margin:0; 71 | } 72 | 73 | 74 | #menu ul li, #subMenu ul li { 75 | float:left; 76 | padding-right:6px; 77 | } 78 | 79 | 80 | 81 | 82 | 83 | 84 | /* Headings */ 85 | 86 | h1 { 87 | font-size:2em; 88 | font-weight:normal; 89 | } 90 | 91 | 92 | h2, h3, h4, h5, th { 93 | font-size:1.3em; 94 | font-weight:normal; 95 | margin-bottom:4px; 96 | } 97 | 98 | 99 | 100 | p { 101 | font-size:1em; 102 | width:90%; 103 | margin-bottom:32px; 104 | } 105 | 106 | 107 | pre, code { 108 | font-family:"Courier New", Courier, monospace; 109 | font-size:1em; 110 | line-height:normal; 111 | } 112 | 113 | 114 | 115 | 116 | hr { 117 | border:0; 118 | height:1px; 119 | margin-bottom:24px; 120 | } 121 | 122 | 123 | a { 124 | text-decoration: underline; 125 | font-weight: normal; 126 | } 127 | 128 | 129 | a:hover, 130 | a:active { 131 | text-decoration: underline; 132 | font-weight: normal; 133 | } 134 | 135 | 136 | a:visited, 137 | a:link:visited { 138 | text-decoration: underline; 139 | font-weight: normal; 140 | } 141 | 142 | 143 | 144 | img { 145 | border: 0px solid #000000; 146 | } 147 | 148 | 149 | 150 | 151 | 152 | /* COLORS */ 153 | 154 | 155 | body { 156 | color : #333; 157 | background-color :#fff; 158 | } 159 | 160 | 161 | #header { 162 | background-color:#fff; 163 | color:#333; 164 | } 165 | 166 | 167 | 168 | h1, h2, h3, h4, h5, h6 { 169 | color:#666; 170 | } 171 | 172 | 173 | pre, code { 174 | color: #000000; 175 | } 176 | 177 | 178 | a,strong { 179 | color: #333; 180 | } 181 | 182 | 183 | a:hover, 184 | a:active { 185 | color: #333; 186 | } 187 | 188 | 189 | a:visited, 190 | a:link:visited { 191 | color: #333; 192 | } 193 | 194 | 195 | #footer, #menu { 196 | background-color:#fff; 197 | color:#333; 198 | } 199 | 200 | 201 | #footer a, #menu a { 202 | color:#333; 203 | } 204 | -------------------------------------------------------------------------------- /resources/library.properties: -------------------------------------------------------------------------------- 1 | # More on this file here: https://github.com/processing/processing/wiki/Library-Basics 2 | # UTF-8 supported. 3 | 4 | # The name of your Library as you want it formatted. 5 | name = ##library.name## 6 | 7 | # List of authors. Links can be provided using the syntax [author name](url). 8 | authors = [##author.name##](##author.url##) 9 | 10 | # A web page for your Library, NOT a direct link to where to download it. 11 | url = ##library.url## 12 | 13 | # The category (or categories) of your Library, must be from the following list: 14 | # "3D" "Animation" "Compilations" "Data" 15 | # "Fabrication" "Geometry" "GUI" "Hardware" 16 | # "I/O" "Language" "Math" "Simulation" 17 | # "Sound" "Utilities" "Typography" "Video & Vision" 18 | # 19 | # If a value other than those listed is used, your Library will listed as 20 | # "Other". Many categories must be comma-separated. 21 | categories = ##library.categories## 22 | 23 | # A short sentence (or fragment) to summarize the Library's function. This will 24 | # be shown from inside the PDE when the Library is being installed. Avoid 25 | # repeating the name of your Library here. Also, avoid saying anything redundant 26 | # like mentioning that it's a Library. This should start with a capitalized 27 | # letter, and end with a period. 28 | sentence = ##library.sentence## 29 | 30 | # Additional information suitable for the Processing website. The value of 31 | # 'sentence' always will be prepended, so you should start by writing the 32 | # second sentence here. If your Library only works on certain operating systems, 33 | # mention it here. 34 | paragraph = ##library.paragraph## 35 | 36 | # Links in the 'sentence' and 'paragraph' attributes can be inserted using the 37 | # same syntax as for authors. 38 | # That is, [here is a link to Processing](http://processing.org/) 39 | 40 | # A version number that increments once with each release. This is used to 41 | # compare different versions of the same Library, and check if an update is 42 | # available. You should think of it as a counter, counting the total number of 43 | # releases you've had. 44 | version = ##library.version## # This must be parsable as an int 45 | 46 | # The version as the user will see it. If blank, the version attribute will be 47 | # used here. This should be a single word, with no spaces. 48 | prettyVersion = ##library.prettyVersion## # This is treated as a String 49 | 50 | # The min and max revision of Processing compatible with your Library. 51 | # Note that these fields use the revision and not the version of Processing, 52 | # parsable as an int. For example, the revision number for 2.2.1 is 227. 53 | # You can find the revision numbers in the change log: https://raw.githubusercontent.com/processing/processing/master/build/shared/revisions.txt 54 | # Only use maxRevision (or minRevision), when your Library is known to 55 | # break in a later (or earlier) release. Otherwise, use the default value 0. 56 | minRevision = ##compatible.minRevision## 57 | maxRevision = ##compatible.maxRevision## 58 | -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | ##library.name## 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 25 | 26 | 38 | 39 |
40 | 41 |
42 |

##library.name##

43 |

44 | A Library by ##author.name## for the Processing programming environment.
45 | Last update, ##date##. 46 |

47 |

48 | ##library.sentence##
49 | ##library.paragraph##
50 | Feel free to replace this paragraph with a description of the Library.
51 | Contributed Libraries are developed, documented, and maintained by members of the Processing community. Further directions are included with each Library. For feedback and support, please post to the Discourse. We strongly encourage all Libraries to be open source, but not all of them are. 52 |

53 |
54 | 55 | 56 | 57 |
58 |

Download

59 |

60 | Download ##library.name## version ##library.prettyVersion## (##library.version##) in 61 | .zip format. 62 |

63 |

Installation

64 |

65 | Unzip and put the extracted ##project.name## folder into the libraries folder of your Processing sketches. Reference and examples are included in the ##project.name## folder. 66 |

67 |
68 | 69 | 70 |
71 |

Keywords. ##library.keywords##

72 |

Reference. Have a look at the javadoc reference here. A copy of the reference is included in the .zip as well.

73 |

Source. The source code of ##library.name## is available at ##source.host##, and its repository can be browsed here.

74 |
75 | 76 | 77 |
78 |

Examples

79 |

Find a list of examples in the current distribution of ##library.name##, or have a look at them by following the links below.

80 |
    81 | ##examples## 82 |
83 |
84 | 85 | 86 |
87 |

Tested

88 |

89 | 90 | Platform ##tested.platform## 91 | 92 | 93 |
Processing ##tested.processingVersion## 94 | 95 | 96 |
Dependencies ##library.dependencies## 97 |

98 |
99 | 100 | 101 | 102 | 114 | 115 | 116 | 121 | 122 | 123 | 127 | 128 | 129 |
130 |
131 | 132 | 135 |
136 | 137 | -------------------------------------------------------------------------------- /resources/build.properties: -------------------------------------------------------------------------------- 1 | # Create a Library for the Processing open source programming language and 2 | # environment (http://processing.org/) 3 | # 4 | # Customize the build properties to make the ant-build-process work for your 5 | # environment. How? Please read the comments below. 6 | # 7 | # The default properties are set for OS X. Please refer to comments for Windows 8 | # settings. 9 | 10 | 11 | # Where is your Processing sketchbook located? 12 | # If you are not sure, check the sketchbook location in your Processing 13 | # application preferences. 14 | # ${user.home} points the compiler to your home directory. 15 | # For windows the default path to your sketchbook would be 16 | # ${user.home}/My Documents/Processing (make adjustments below) 17 | 18 | #sketchbook.location=${user.home}/My Documents/Processing 19 | sketchbook.location=${user.home}/Documents/Processing 20 | 21 | 22 | # Where are the jar files located that are required for compiling your Library 23 | # such as e.g. core.jar? 24 | # By default the local classpath location points to folder libs inside Eclipse's 25 | # workspace (by default found in your home directory). 26 | # For Windows, the default path would be 27 | # ${user.home}/Documents/workspace/libs (make adjustments below) 28 | # For OS X,the following path will direct you into Processing's application 29 | # package, in case you put Processing inside your Applications folder. 30 | 31 | classpath.local.location=${user.home}/Desktop/OpenSimplexNoise-for-Processing/lib 32 | #classpath.local.location=/Applications/Processing.app/Contents/Java/core/library 33 | 34 | 35 | # Add all jar files that are required for compiling your project to the local 36 | # and project classpath. Use a comma as delimiter. These jar files must be 37 | # inside your classpath.local.location folder. 38 | 39 | classpath.local.include=core.jar 40 | 41 | 42 | # Add Processing's libraries folder to the classpath. 43 | # If you don't need to include the libraries folder to your classpath, comment 44 | # out the following line. 45 | 46 | classpath.libraries.location=${sketchbook.location}/libraries 47 | 48 | 49 | # Set the java version that should be used to compile your Library. 50 | 51 | java.target.version=1.8 52 | 53 | 54 | # Set the description of the Ant build.xml file. 55 | 56 | ant.description=Processing Library Ant build file. 57 | 58 | 59 | # Give your Library a name. The name must not contain spaces or special 60 | # characters. 61 | 62 | project.name=OpenSimplexNoise 63 | 64 | 65 | # The name as the user will see it. This can contain spaces and special 66 | # characters. 67 | 68 | project.prettyName=OpenSimplexNoise for Processing 69 | 70 | 71 | # Use 'normal' or 'fast' as value for project.compile. 72 | # 'fast' will only compile the project into your sketchbook. 73 | # 'normal' will compile the distribution including the javadoc-reference and all 74 | # web-files (the compile process here takes longer). 75 | # All files compiled with project.compile=normal are stored in the distribution 76 | # folder. 77 | 78 | project.compile=normal 79 | 80 | 81 | # Set your name and URL, used for the web page and properties file. 82 | 83 | author.name=The Coding Train 84 | author.url=http://thecodingtrain.com 85 | 86 | 87 | # Set the web page for your Library. 88 | # This is NOT a direct link to where to download it. 89 | 90 | library.url=http://thecodingtrain.com 91 | 92 | 93 | # Set the category (or categories) of your Library from the following list: 94 | # "3D" "Animation" "Compilations" "Data" 95 | # "Fabrication" "Geometry" "GUI" "Hardware" 96 | # "I/O" "Language" "Math" "Simulation" 97 | # "Sound" "Utilities" "Typography" "Video & Vision" 98 | # 99 | # If a value other than those listed is used, your Library will listed as 100 | # "Other". Many categories must be comma-separated. 101 | 102 | library.categories=Math 103 | 104 | 105 | # A short sentence (or fragment) to summarize the Library's function. This will 106 | # be shown from inside the PDE when the Library is being installed. Avoid 107 | # repeating the name of your Library here. Also, avoid saying anything redundant 108 | # like mentioning that it's a Library. This should start with a capitalized 109 | # letter, and end with a period. 110 | 111 | library.sentence=A collection of utilities for solving this and that problem. 112 | 113 | 114 | # Additional information suitable for the Processing website. The value of 115 | # 'sentence' always will be prepended, so you should start by writing the 116 | # second sentence here. If your Library only works on certain operating systems, 117 | # mention it here. 118 | 119 | library.paragraph= 120 | 121 | 122 | # Set the source code repository for your project. 123 | # We recommend Bitbucket (https://bitbucket.org) or GitHub (https://github.com). 124 | 125 | source.host=GitHub 126 | source.url=https://github.com/YourName/YourProject 127 | source.repository=https://github.com/YourName/YourProject.git 128 | 129 | 130 | # The current version of your Library. 131 | # This number must be parsable as an int. It increments once with each release. 132 | # This is used to compare different versions of the same Library, and check if 133 | # an update is available. 134 | 135 | library.version=1 136 | 137 | 138 | # The version as the user will see it. 139 | 140 | library.prettyVersion=1.0.0 141 | 142 | 143 | # The min and max revision of Processing compatible with your Library. 144 | # Note that these fields use the revision and not the version of Processing, 145 | # parsable as an int. For example, the revision number for 2.2.1 is 227. 146 | # You can find the revision numbers in the change log: https://raw.githubusercontent.com/processing/processing/master/build/shared/revisions.txt 147 | # Only use maxRevision (or minRevision), when your Library is known to 148 | # break in a later (or earlier) release. Otherwise, use the default value 0. 149 | 150 | compatible.minRevision=0 151 | compatible.maxRevision=0 152 | 153 | 154 | # The platforms and Processing version that the Library has been tested 155 | # against. This information is only used in the generated webpage. 156 | 157 | tested.platform=osx,windows 158 | tested.processingVersion=3.2.3 159 | 160 | 161 | # Additional information for the generated webpage. 162 | 163 | library.copyright=(c) 2016 164 | library.dependencies=? 165 | library.keywords=? 166 | 167 | 168 | # Include javadoc references into your project's javadocs. 169 | 170 | #javadoc.java.href=http://docs.oracle.com/javase/7/docs/api/ 171 | javadoc.java.href=http://docs.oracle.com/javase/8/docs/api/ 172 | javadoc.processing.href=http://processing.github.io/processing-javadocs/core/ 173 | -------------------------------------------------------------------------------- /resources/code/ExampleTaglet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or 5 | * without modification, are permitted provided that the following 6 | * conditions are met: 7 | * 8 | * -Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 11 | * -Redistribution in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in 13 | * the documentation and/or other materials provided with the 14 | * distribution. 15 | * 16 | * Neither the name of Sun Microsystems, Inc. or the names of 17 | * contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * This software is provided "AS IS," without a warranty of any 21 | * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND 22 | * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, 23 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY 24 | * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY 25 | * DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR 26 | * RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR 27 | * ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE 28 | * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, 29 | * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER 30 | * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF 31 | * THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN 32 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 33 | * 34 | * You acknowledge that Software is not designed, licensed or 35 | * intended for use in the design, construction, operation or 36 | * maintenance of any nuclear facility. 37 | */ 38 | 39 | import com.sun.tools.doclets.Taglet; 40 | import com.sun.javadoc.*; 41 | import java.util.Map; 42 | import java.io.*; 43 | /** 44 | * A sample Taglet representing @example. This tag can be used in any kind of 45 | * {@link com.sun.javadoc.Doc}. It is not an inline tag. The text is displayed 46 | * in yellow to remind the developer to perform a task. For 47 | * example, "@example Hello" would be shown as: 48 | *
49 | *
50 | * To Do: 51 | *
Fix this! 52 | *
53 | *
54 | * 55 | * @author Jamie Ho 56 | * @since 1.4 57 | */ 58 | 59 | public class ExampleTaglet implements Taglet { 60 | 61 | private static final String NAME = "example"; 62 | private static final String HEADER = "example To Do:"; 63 | 64 | /** 65 | * Return the name of this custom tag. 66 | */ 67 | public String getName() { 68 | return NAME; 69 | } 70 | 71 | /** 72 | * Will return true since @example 73 | * can be used in field documentation. 74 | * @return true since @example 75 | * can be used in field documentation and false 76 | * otherwise. 77 | */ 78 | public boolean inField() { 79 | return true; 80 | } 81 | 82 | /** 83 | * Will return true since @example 84 | * can be used in constructor documentation. 85 | * @return true since @example 86 | * can be used in constructor documentation and false 87 | * otherwise. 88 | */ 89 | public boolean inConstructor() { 90 | return true; 91 | } 92 | 93 | /** 94 | * Will return true since @example 95 | * can be used in method documentation. 96 | * @return true since @example 97 | * can be used in method documentation and false 98 | * otherwise. 99 | */ 100 | public boolean inMethod() { 101 | return true; 102 | } 103 | 104 | /** 105 | * Will return true since @example 106 | * can be used in method documentation. 107 | * @return true since @example 108 | * can be used in overview documentation and false 109 | * otherwise. 110 | */ 111 | public boolean inOverview() { 112 | return true; 113 | } 114 | 115 | /** 116 | * Will return true since @example 117 | * can be used in package documentation. 118 | * @return true since @example 119 | * can be used in package documentation and false 120 | * otherwise. 121 | */ 122 | public boolean inPackage() { 123 | return true; 124 | } 125 | 126 | /** 127 | * Will return true since @example 128 | * can be used in type documentation (classes or interfaces). 129 | * @return true since @example 130 | * can be used in type documentation and false 131 | * otherwise. 132 | */ 133 | public boolean inType() { 134 | return true; 135 | } 136 | 137 | /** 138 | * Will return false since @example 139 | * is not an inline tag. 140 | * @return false since @example 141 | * is not an inline tag. 142 | */ 143 | 144 | public boolean isInlineTag() { 145 | return false; 146 | } 147 | 148 | /** 149 | * Register this Taglet. 150 | * @param tagletMap the map to register this tag to. 151 | */ 152 | public static void register(Map tagletMap) { 153 | ExampleTaglet tag = new ExampleTaglet(); 154 | Taglet t = (Taglet) tagletMap.get(tag.getName()); 155 | if (t != null) { 156 | tagletMap.remove(tag.getName()); 157 | } 158 | tagletMap.put(tag.getName(), tag); 159 | } 160 | 161 | /** 162 | * Given the Tag representation of this custom 163 | * tag, return its string representation. 164 | * @param tag the Tag representation of this custom tag. 165 | */ 166 | public String toString(Tag tag) { 167 | return createHTML(readFile(tag.text())); 168 | } 169 | 170 | 171 | /** 172 | * Given an array of Tags representing this custom 173 | * tag, return its string representation. 174 | * @param tags the array of Tags representing of this custom tag. 175 | */ 176 | public String toString(Tag[] tags) { 177 | if (tags.length == 0) { 178 | return null; 179 | } 180 | return createHTML(readFile(tags[0].text())); 181 | } 182 | 183 | 184 | 185 | String createHTML(String theString) { 186 | if(theString!=null) { 187 | String dd = ""; 193 | 194 | return dd+"\n
" + 195 | "
+Example
" + 196 | "
"+theString+"
" + 197 | "
"; 198 | } 199 | return ""; 200 | } 201 | 202 | 203 | /** 204 | * check if the examples directory exists and return the example as given in the tag. 205 | * @param theExample the name of the example 206 | */ 207 | String readFile(String theExample) { 208 | String record = ""; 209 | String myResult = ""; 210 | int recCount = 0; 211 | String myDir = "../examples"; 212 | File file=new File(myDir); 213 | if(file.exists()==false) { 214 | myDir = "./examples"; 215 | } 216 | try { 217 | FileReader fr = new FileReader(myDir+"/"+theExample+"/"+theExample+".pde"); 218 | BufferedReader br = new BufferedReader(fr); 219 | record = new String(); 220 | while ((record = br.readLine()) != null) { 221 | myResult += record+"\n"; 222 | } 223 | } catch (IOException e) { 224 | System.out.println(e); 225 | return null; 226 | } 227 | return myResult; 228 | } 229 | } 230 | 231 | 232 | -------------------------------------------------------------------------------- /resources/stylesheet.css: -------------------------------------------------------------------------------- 1 | /* Javadoc style sheet */ 2 | /* 3 | Overall document style 4 | */ 5 | 6 | @import url('resources/fonts/dejavu.css'); 7 | 8 | body { 9 | background-color:#ffffff; 10 | color:#353833; 11 | font-family:'DejaVu Sans', Arial, Helvetica, sans-serif; 12 | font-size:14px; 13 | margin:0; 14 | } 15 | a:link, a:visited { 16 | text-decoration:none; 17 | color:#4A6782; 18 | } 19 | a:hover, a:focus { 20 | text-decoration:none; 21 | color:#bb7a2a; 22 | } 23 | a:active { 24 | text-decoration:none; 25 | color:#4A6782; 26 | } 27 | a[name] { 28 | color:#353833; 29 | } 30 | a[name]:hover { 31 | text-decoration:none; 32 | color:#353833; 33 | } 34 | pre { 35 | font-family:'DejaVu Sans Mono', monospace; 36 | font-size:14px; 37 | } 38 | h1 { 39 | font-size:20px; 40 | } 41 | h2 { 42 | font-size:18px; 43 | } 44 | h3 { 45 | font-size:16px; 46 | font-style:italic; 47 | } 48 | h4 { 49 | font-size:13px; 50 | } 51 | h5 { 52 | font-size:12px; 53 | } 54 | h6 { 55 | font-size:11px; 56 | } 57 | ul { 58 | list-style-type:disc; 59 | } 60 | code, tt { 61 | font-family:'DejaVu Sans Mono', monospace; 62 | font-size:14px; 63 | padding-top:4px; 64 | margin-top:8px; 65 | line-height:1.4em; 66 | } 67 | dt code { 68 | font-family:'DejaVu Sans Mono', monospace; 69 | font-size:14px; 70 | padding-top:4px; 71 | } 72 | table tr td dt code { 73 | font-family:'DejaVu Sans Mono', monospace; 74 | font-size:14px; 75 | vertical-align:top; 76 | padding-top:4px; 77 | } 78 | sup { 79 | font-size:8px; 80 | } 81 | /* 82 | Document title and Copyright styles 83 | */ 84 | .clear { 85 | clear:both; 86 | height:0px; 87 | overflow:hidden; 88 | } 89 | .aboutLanguage { 90 | float:right; 91 | padding:0px 21px; 92 | font-size:11px; 93 | z-index:200; 94 | margin-top:-9px; 95 | } 96 | .legalCopy { 97 | margin-left:.5em; 98 | } 99 | .bar a, .bar a:link, .bar a:visited, .bar a:active { 100 | color:#FFFFFF; 101 | text-decoration:none; 102 | } 103 | .bar a:hover, .bar a:focus { 104 | color:#bb7a2a; 105 | } 106 | .tab { 107 | background-color:#0066FF; 108 | color:#ffffff; 109 | padding:8px; 110 | width:5em; 111 | font-weight:bold; 112 | } 113 | /* 114 | Navigation bar styles 115 | */ 116 | .bar { 117 | background-color:#4D7A97; 118 | color:#FFFFFF; 119 | padding:.8em .5em .4em .8em; 120 | height:auto;/*height:1.8em;*/ 121 | font-size:11px; 122 | margin:0; 123 | } 124 | .topNav { 125 | background-color:#4D7A97; 126 | color:#FFFFFF; 127 | float:left; 128 | padding:0; 129 | width:100%; 130 | clear:right; 131 | height:2.8em; 132 | padding-top:10px; 133 | overflow:hidden; 134 | font-size:12px; 135 | } 136 | .bottomNav { 137 | margin-top:10px; 138 | background-color:#4D7A97; 139 | color:#FFFFFF; 140 | float:left; 141 | padding:0; 142 | width:100%; 143 | clear:right; 144 | height:2.8em; 145 | padding-top:10px; 146 | overflow:hidden; 147 | font-size:12px; 148 | } 149 | .subNav { 150 | background-color:#dee3e9; 151 | float:left; 152 | width:100%; 153 | overflow:hidden; 154 | font-size:12px; 155 | } 156 | .subNav div { 157 | clear:left; 158 | float:left; 159 | padding:0 0 5px 6px; 160 | text-transform:uppercase; 161 | } 162 | ul.navList, ul.subNavList { 163 | float:left; 164 | margin:0 25px 0 0; 165 | padding:0; 166 | } 167 | ul.navList li{ 168 | list-style:none; 169 | float:left; 170 | padding: 5px 6px; 171 | text-transform:uppercase; 172 | } 173 | ul.subNavList li{ 174 | list-style:none; 175 | float:left; 176 | } 177 | .topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { 178 | color:#FFFFFF; 179 | text-decoration:none; 180 | text-transform:uppercase; 181 | } 182 | .topNav a:hover, .bottomNav a:hover { 183 | text-decoration:none; 184 | color:#bb7a2a; 185 | text-transform:uppercase; 186 | } 187 | .navBarCell1Rev { 188 | background-color:#F8981D; 189 | color:#253441; 190 | margin: auto 5px; 191 | } 192 | .skipNav { 193 | position:absolute; 194 | top:auto; 195 | left:-9999px; 196 | overflow:hidden; 197 | } 198 | /* 199 | Page header and footer styles 200 | */ 201 | .header, .footer { 202 | clear:both; 203 | margin:0 20px; 204 | padding:5px 0 0 0; 205 | } 206 | .indexHeader { 207 | margin:10px; 208 | position:relative; 209 | } 210 | .indexHeader span{ 211 | margin-right:15px; 212 | } 213 | .indexHeader h1 { 214 | font-size:13px; 215 | } 216 | .title { 217 | color:#2c4557; 218 | margin:10px 0; 219 | } 220 | .subTitle { 221 | margin:5px 0 0 0; 222 | } 223 | .header ul { 224 | margin:0 0 15px 0; 225 | padding:0; 226 | } 227 | .footer ul { 228 | margin:20px 0 5px 0; 229 | } 230 | .header ul li, .footer ul li { 231 | list-style:none; 232 | font-size:13px; 233 | } 234 | /* 235 | Heading styles 236 | */ 237 | div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { 238 | background-color:#dee3e9; 239 | border:1px solid #d0d9e0; 240 | margin:0 0 6px -8px; 241 | padding:7px 5px; 242 | } 243 | ul.blockList ul.blockList ul.blockList li.blockList h3 { 244 | background-color:#dee3e9; 245 | border:1px solid #d0d9e0; 246 | margin:0 0 6px -8px; 247 | padding:7px 5px; 248 | } 249 | ul.blockList ul.blockList li.blockList h3 { 250 | padding:0; 251 | margin:15px 0; 252 | } 253 | ul.blockList li.blockList h2 { 254 | padding:0px 0 20px 0; 255 | } 256 | /* 257 | Page layout container styles 258 | */ 259 | .contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { 260 | clear:both; 261 | padding:10px 20px; 262 | position:relative; 263 | } 264 | .indexContainer { 265 | margin:10px; 266 | position:relative; 267 | font-size:12px; 268 | } 269 | .indexContainer h2 { 270 | font-size:13px; 271 | padding:0 0 3px 0; 272 | } 273 | .indexContainer ul { 274 | margin:0; 275 | padding:0; 276 | } 277 | .indexContainer ul li { 278 | list-style:none; 279 | padding-top:2px; 280 | } 281 | .contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { 282 | font-size:12px; 283 | font-weight:bold; 284 | margin:10px 0 0 0; 285 | color:#4E4E4E; 286 | } 287 | .contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { 288 | margin:5px 0 10px 0px; 289 | font-size:14px; 290 | font-family:'DejaVu Sans Mono',monospace; 291 | } 292 | .serializedFormContainer dl.nameValue dt { 293 | margin-left:1px; 294 | font-size:1.1em; 295 | display:inline; 296 | font-weight:bold; 297 | } 298 | .serializedFormContainer dl.nameValue dd { 299 | margin:0 0 0 1px; 300 | font-size:1.1em; 301 | display:inline; 302 | } 303 | /* 304 | List styles 305 | */ 306 | ul.horizontal li { 307 | display:inline; 308 | font-size:0.9em; 309 | } 310 | ul.inheritance { 311 | margin:0; 312 | padding:0; 313 | } 314 | ul.inheritance li { 315 | display:inline; 316 | list-style:none; 317 | } 318 | ul.inheritance li ul.inheritance { 319 | margin-left:15px; 320 | padding-left:15px; 321 | padding-top:1px; 322 | } 323 | ul.blockList, ul.blockListLast { 324 | margin:10px 0 10px 0; 325 | padding:0; 326 | } 327 | ul.blockList li.blockList, ul.blockListLast li.blockList { 328 | list-style:none; 329 | margin-bottom:15px; 330 | line-height:1.4; 331 | } 332 | ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { 333 | padding:0px 20px 5px 10px; 334 | border:1px solid #ededed; 335 | background-color:#f8f8f8; 336 | } 337 | ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { 338 | padding:0 0 5px 8px; 339 | background-color:#ffffff; 340 | border:none; 341 | } 342 | ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { 343 | margin-left:0; 344 | padding-left:0; 345 | padding-bottom:15px; 346 | border:none; 347 | } 348 | ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { 349 | list-style:none; 350 | border-bottom:none; 351 | padding-bottom:0; 352 | } 353 | table tr td dl, table tr td dl dt, table tr td dl dd { 354 | margin-top:0; 355 | margin-bottom:1px; 356 | } 357 | /* 358 | Table styles 359 | */ 360 | .overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary { 361 | width:100%; 362 | border-left:1px solid #EEE; 363 | border-right:1px solid #EEE; 364 | border-bottom:1px solid #EEE; 365 | } 366 | .overviewSummary, .memberSummary { 367 | padding:0px; 368 | } 369 | .overviewSummary caption, .memberSummary caption, .typeSummary caption, 370 | .useSummary caption, .constantsSummary caption, .deprecatedSummary caption { 371 | position:relative; 372 | text-align:left; 373 | background-repeat:no-repeat; 374 | color:#253441; 375 | font-weight:bold; 376 | clear:none; 377 | overflow:hidden; 378 | padding:0px; 379 | padding-top:10px; 380 | padding-left:1px; 381 | margin:0px; 382 | white-space:pre; 383 | } 384 | .overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link, 385 | .useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link, 386 | .overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover, 387 | .useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover, 388 | .overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active, 389 | .useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active, 390 | .overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited, 391 | .useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited { 392 | color:#FFFFFF; 393 | } 394 | .overviewSummary caption span, .memberSummary caption span, .typeSummary caption span, 395 | .useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span { 396 | white-space:nowrap; 397 | padding-top:5px; 398 | padding-left:12px; 399 | padding-right:12px; 400 | padding-bottom:7px; 401 | display:inline-block; 402 | float:left; 403 | background-color:#F8981D; 404 | border: none; 405 | height:16px; 406 | } 407 | .memberSummary caption span.activeTableTab span { 408 | white-space:nowrap; 409 | padding-top:5px; 410 | padding-left:12px; 411 | padding-right:12px; 412 | margin-right:3px; 413 | display:inline-block; 414 | float:left; 415 | background-color:#F8981D; 416 | height:16px; 417 | } 418 | .memberSummary caption span.tableTab span { 419 | white-space:nowrap; 420 | padding-top:5px; 421 | padding-left:12px; 422 | padding-right:12px; 423 | margin-right:3px; 424 | display:inline-block; 425 | float:left; 426 | background-color:#4D7A97; 427 | height:16px; 428 | } 429 | .memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab { 430 | padding-top:0px; 431 | padding-left:0px; 432 | padding-right:0px; 433 | background-image:none; 434 | float:none; 435 | display:inline; 436 | } 437 | .overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd, 438 | .useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd { 439 | display:none; 440 | width:5px; 441 | position:relative; 442 | float:left; 443 | background-color:#F8981D; 444 | } 445 | .memberSummary .activeTableTab .tabEnd { 446 | display:none; 447 | width:5px; 448 | margin-right:3px; 449 | position:relative; 450 | float:left; 451 | background-color:#F8981D; 452 | } 453 | .memberSummary .tableTab .tabEnd { 454 | display:none; 455 | width:5px; 456 | margin-right:3px; 457 | position:relative; 458 | background-color:#4D7A97; 459 | float:left; 460 | 461 | } 462 | .overviewSummary td, .memberSummary td, .typeSummary td, 463 | .useSummary td, .constantsSummary td, .deprecatedSummary td { 464 | text-align:left; 465 | padding:0px 0px 12px 10px; 466 | } 467 | th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th, 468 | td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{ 469 | vertical-align:top; 470 | padding-right:0px; 471 | padding-top:8px; 472 | padding-bottom:3px; 473 | } 474 | th.colFirst, th.colLast, th.colOne, .constantsSummary th { 475 | background:#dee3e9; 476 | text-align:left; 477 | padding:8px 3px 3px 7px; 478 | } 479 | td.colFirst, th.colFirst { 480 | white-space:nowrap; 481 | font-size:13px; 482 | } 483 | td.colLast, th.colLast { 484 | font-size:13px; 485 | } 486 | td.colOne, th.colOne { 487 | font-size:13px; 488 | } 489 | .overviewSummary td.colFirst, .overviewSummary th.colFirst, 490 | .useSummary td.colFirst, .useSummary th.colFirst, 491 | .overviewSummary td.colOne, .overviewSummary th.colOne, 492 | .memberSummary td.colFirst, .memberSummary th.colFirst, 493 | .memberSummary td.colOne, .memberSummary th.colOne, 494 | .typeSummary td.colFirst{ 495 | width:25%; 496 | vertical-align:top; 497 | } 498 | td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { 499 | font-weight:bold; 500 | } 501 | .tableSubHeadingColor { 502 | background-color:#EEEEFF; 503 | } 504 | .altColor { 505 | background-color:#FFFFFF; 506 | } 507 | .rowColor { 508 | background-color:#EEEEEF; 509 | } 510 | /* 511 | Content styles 512 | */ 513 | .description pre { 514 | margin-top:0; 515 | } 516 | .deprecatedContent { 517 | margin:0; 518 | padding:10px 0; 519 | } 520 | .docSummary { 521 | padding:0; 522 | } 523 | 524 | ul.blockList ul.blockList ul.blockList li.blockList h3 { 525 | font-style:normal; 526 | } 527 | 528 | div.block { 529 | font-size:14px; 530 | font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; 531 | } 532 | 533 | td.colLast div { 534 | padding-top:0px; 535 | } 536 | 537 | 538 | td.colLast a { 539 | padding-bottom:3px; 540 | } 541 | /* 542 | Formatting effect styles 543 | */ 544 | .sourceLineNo { 545 | color:green; 546 | padding:0 30px 0 0; 547 | } 548 | h1.hidden { 549 | visibility:hidden; 550 | overflow:hidden; 551 | font-size:10px; 552 | } 553 | .block { 554 | display:block; 555 | margin:3px 10px 2px 0px; 556 | color:#474747; 557 | } 558 | .deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink, 559 | .overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel, 560 | .seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink { 561 | font-weight:bold; 562 | } 563 | .deprecationComment, .emphasizedPhrase, .interfaceName { 564 | font-style:italic; 565 | } 566 | 567 | div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase, 568 | div.block div.block span.interfaceName { 569 | font-style:normal; 570 | } 571 | 572 | div.contentContainer ul.blockList li.blockList h2{ 573 | padding-bottom:0px; 574 | } -------------------------------------------------------------------------------- /resources/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | ${ant.description} 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | ${line} 81 | Building the Processing Library ${project.name} ${library.version} 82 | ${line} 83 | src path ${project.src} 84 | bin path ${project.bin} 85 | classpath.local ${classpath.local.location} 86 | sketchbook ${sketchbook.location} 87 | java version ${java.target.version} 88 | ${line} 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | ${exampleDir} 342 | 348 | 349 | 355 | 356 | 357 | 358 | 359 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | ${line} 377 | Name ${project.name} 378 | Version ${library.prettyVersion} (${library.version}) 379 | Compiled ${project.compile} 380 | Sketchbook ${sketchbook.location} 381 | ${line} 382 | done, finished. 383 | ${line} 384 | 385 | 386 | 387 | 388 | 389 | -------------------------------------------------------------------------------- /src/algorithms/noise/OpenSimplexNoiseKS.java: -------------------------------------------------------------------------------- 1 | package algorithms.noise; 2 | /* 3 | * OpenSimplex Noise in Java. 4 | * by Kurt Spencer 5 | * 6 | * v1.1 (October 5, 2014) 7 | * - Added 2D and 4D implementations. 8 | * - Proper gradient sets for all dimensions, from a 9 | * dimensionally-generalizable scheme with an actual 10 | * rhyme and reason behind it. 11 | * - Removed default permutation array in favor of 12 | * default seed. 13 | * - Changed seed-based constructor to be independent 14 | * of any particular randomization library, so results 15 | * will be the same when ported to other languages. 16 | */ 17 | 18 | class OpenSimplexNoiseKS { 19 | 20 | private static final double STRETCH_CONSTANT_2D = -0.211324865405187; //(1/Math.sqrt(2+1)-1)/2; 21 | private static final double SQUISH_CONSTANT_2D = 0.366025403784439; //(Math.sqrt(2+1)-1)/2; 22 | private static final double STRETCH_CONSTANT_3D = -1.0 / 6; //(1/Math.sqrt(3+1)-1)/3; 23 | private static final double SQUISH_CONSTANT_3D = 1.0 / 3; //(Math.sqrt(3+1)-1)/3; 24 | private static final double STRETCH_CONSTANT_4D = -0.138196601125011; //(1/Math.sqrt(4+1)-1)/4; 25 | private static final double SQUISH_CONSTANT_4D = 0.309016994374947; //(Math.sqrt(4+1)-1)/4; 26 | 27 | private static final double NORM_CONSTANT_2D = 47; 28 | private static final double NORM_CONSTANT_3D = 103; 29 | private static final double NORM_CONSTANT_4D = 30; 30 | 31 | private static final long DEFAULT_SEED = 0; 32 | 33 | private short[] perm; 34 | private short[] permGradIndex3D; 35 | 36 | public OpenSimplexNoiseKS() { 37 | this(DEFAULT_SEED); 38 | } 39 | 40 | public OpenSimplexNoiseKS(short[] perm) { 41 | this.perm = perm; 42 | permGradIndex3D = new short[256]; 43 | 44 | for (int i = 0; i < 256; i++) { 45 | //Since 3D has 24 gradients, simple bitmask won't work, so precompute modulo array. 46 | permGradIndex3D[i] = (short)((perm[i] % (gradients3D.length / 3)) * 3); 47 | } 48 | } 49 | 50 | //Initializes the class using a permutation array generated from a 64-bit seed. 51 | //Generates a proper permutation (i.e. doesn't merely perform N successive pair swaps on a base array) 52 | //Uses a simple 64-bit LCG. 53 | public OpenSimplexNoiseKS(long seed) { 54 | perm = new short[256]; 55 | permGradIndex3D = new short[256]; 56 | short[] source = new short[256]; 57 | for (short i = 0; i < 256; i++) 58 | source[i] = i; 59 | seed = seed * 6364136223846793005l + 1442695040888963407l; 60 | seed = seed * 6364136223846793005l + 1442695040888963407l; 61 | seed = seed * 6364136223846793005l + 1442695040888963407l; 62 | for (int i = 255; i >= 0; i--) { 63 | seed = seed * 6364136223846793005l + 1442695040888963407l; 64 | int r = (int)((seed + 31) % (i + 1)); 65 | if (r < 0) 66 | r += (i + 1); 67 | perm[i] = source[r]; 68 | permGradIndex3D[i] = (short)((perm[i] % (gradients3D.length / 3)) * 3); 69 | source[r] = source[i]; 70 | } 71 | } 72 | 73 | //2D OpenSimplex Noise. 74 | public double eval(double x, double y) { 75 | 76 | //Place input coordinates onto grid. 77 | double stretchOffset = (x + y) * STRETCH_CONSTANT_2D; 78 | double xs = x + stretchOffset; 79 | double ys = y + stretchOffset; 80 | 81 | //Floor to get grid coordinates of rhombus (stretched square) super-cell origin. 82 | int xsb = fastFloor(xs); 83 | int ysb = fastFloor(ys); 84 | 85 | //Skew out to get actual coordinates of rhombus origin. We'll need these later. 86 | double squishOffset = (xsb + ysb) * SQUISH_CONSTANT_2D; 87 | double xb = xsb + squishOffset; 88 | double yb = ysb + squishOffset; 89 | 90 | //Compute grid coordinates relative to rhombus origin. 91 | double xins = xs - xsb; 92 | double yins = ys - ysb; 93 | 94 | //Sum those together to get a value that determines which region we're in. 95 | double inSum = xins + yins; 96 | 97 | //Positions relative to origin point. 98 | double dx0 = x - xb; 99 | double dy0 = y - yb; 100 | 101 | //We'll be defining these inside the next block and using them afterwards. 102 | double dx_ext, dy_ext; 103 | int xsv_ext, ysv_ext; 104 | 105 | double value = 0; 106 | 107 | //Contribution (1,0) 108 | double dx1 = dx0 - 1 - SQUISH_CONSTANT_2D; 109 | double dy1 = dy0 - 0 - SQUISH_CONSTANT_2D; 110 | double attn1 = 2 - dx1 * dx1 - dy1 * dy1; 111 | if (attn1 > 0) { 112 | attn1 *= attn1; 113 | value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, dx1, dy1); 114 | } 115 | 116 | //Contribution (0,1) 117 | double dx2 = dx0 - 0 - SQUISH_CONSTANT_2D; 118 | double dy2 = dy0 - 1 - SQUISH_CONSTANT_2D; 119 | double attn2 = 2 - dx2 * dx2 - dy2 * dy2; 120 | if (attn2 > 0) { 121 | attn2 *= attn2; 122 | value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, dx2, dy2); 123 | } 124 | 125 | if (inSum <= 1) { //We're inside the triangle (2-Simplex) at (0,0) 126 | double zins = 1 - inSum; 127 | if (zins > xins || zins > yins) { //(0,0) is one of the closest two triangular vertices 128 | if (xins > yins) { 129 | xsv_ext = xsb + 1; 130 | ysv_ext = ysb - 1; 131 | dx_ext = dx0 - 1; 132 | dy_ext = dy0 + 1; 133 | } else { 134 | xsv_ext = xsb - 1; 135 | ysv_ext = ysb + 1; 136 | dx_ext = dx0 + 1; 137 | dy_ext = dy0 - 1; 138 | } 139 | } else { //(1,0) and (0,1) are the closest two vertices. 140 | xsv_ext = xsb + 1; 141 | ysv_ext = ysb + 1; 142 | dx_ext = dx0 - 1 - 2 * SQUISH_CONSTANT_2D; 143 | dy_ext = dy0 - 1 - 2 * SQUISH_CONSTANT_2D; 144 | } 145 | } else { //We're inside the triangle (2-Simplex) at (1,1) 146 | double zins = 2 - inSum; 147 | if (zins < xins || zins < yins) { //(0,0) is one of the closest two triangular vertices 148 | if (xins > yins) { 149 | xsv_ext = xsb + 2; 150 | ysv_ext = ysb + 0; 151 | dx_ext = dx0 - 2 - 2 * SQUISH_CONSTANT_2D; 152 | dy_ext = dy0 + 0 - 2 * SQUISH_CONSTANT_2D; 153 | } else { 154 | xsv_ext = xsb + 0; 155 | ysv_ext = ysb + 2; 156 | dx_ext = dx0 + 0 - 2 * SQUISH_CONSTANT_2D; 157 | dy_ext = dy0 - 2 - 2 * SQUISH_CONSTANT_2D; 158 | } 159 | } else { //(1,0) and (0,1) are the closest two vertices. 160 | dx_ext = dx0; 161 | dy_ext = dy0; 162 | xsv_ext = xsb; 163 | ysv_ext = ysb; 164 | } 165 | xsb += 1; 166 | ysb += 1; 167 | dx0 = dx0 - 1 - 2 * SQUISH_CONSTANT_2D; 168 | dy0 = dy0 - 1 - 2 * SQUISH_CONSTANT_2D; 169 | } 170 | 171 | //Contribution (0,0) or (1,1) 172 | double attn0 = 2 - dx0 * dx0 - dy0 * dy0; 173 | if (attn0 > 0) { 174 | attn0 *= attn0; 175 | value += attn0 * attn0 * extrapolate(xsb, ysb, dx0, dy0); 176 | } 177 | 178 | //Extra Vertex 179 | double attn_ext = 2 - dx_ext * dx_ext - dy_ext * dy_ext; 180 | if (attn_ext > 0) { 181 | attn_ext *= attn_ext; 182 | value += attn_ext * attn_ext * extrapolate(xsv_ext, ysv_ext, dx_ext, dy_ext); 183 | } 184 | 185 | return value / NORM_CONSTANT_2D; 186 | } 187 | 188 | //3D OpenSimplex Noise. 189 | public double eval(double x, double y, double z) { 190 | 191 | //Place input coordinates on simplectic honeycomb. 192 | double stretchOffset = (x + y + z) * STRETCH_CONSTANT_3D; 193 | double xs = x + stretchOffset; 194 | double ys = y + stretchOffset; 195 | double zs = z + stretchOffset; 196 | 197 | //Floor to get simplectic honeycomb coordinates of rhombohedron (stretched cube) super-cell origin. 198 | int xsb = fastFloor(xs); 199 | int ysb = fastFloor(ys); 200 | int zsb = fastFloor(zs); 201 | 202 | //Skew out to get actual coordinates of rhombohedron origin. We'll need these later. 203 | double squishOffset = (xsb + ysb + zsb) * SQUISH_CONSTANT_3D; 204 | double xb = xsb + squishOffset; 205 | double yb = ysb + squishOffset; 206 | double zb = zsb + squishOffset; 207 | 208 | //Compute simplectic honeycomb coordinates relative to rhombohedral origin. 209 | double xins = xs - xsb; 210 | double yins = ys - ysb; 211 | double zins = zs - zsb; 212 | 213 | //Sum those together to get a value that determines which region we're in. 214 | double inSum = xins + yins + zins; 215 | 216 | //Positions relative to origin point. 217 | double dx0 = x - xb; 218 | double dy0 = y - yb; 219 | double dz0 = z - zb; 220 | 221 | //We'll be defining these inside the next block and using them afterwards. 222 | double dx_ext0, dy_ext0, dz_ext0; 223 | double dx_ext1, dy_ext1, dz_ext1; 224 | int xsv_ext0, ysv_ext0, zsv_ext0; 225 | int xsv_ext1, ysv_ext1, zsv_ext1; 226 | 227 | double value = 0; 228 | if (inSum <= 1) { //We're inside the tetrahedron (3-Simplex) at (0,0,0) 229 | 230 | //Determine which two of (0,0,1), (0,1,0), (1,0,0) are closest. 231 | byte aPoint = 0x01; 232 | double aScore = xins; 233 | byte bPoint = 0x02; 234 | double bScore = yins; 235 | if (aScore >= bScore && zins > bScore) { 236 | bScore = zins; 237 | bPoint = 0x04; 238 | } else if (aScore < bScore && zins > aScore) { 239 | aScore = zins; 240 | aPoint = 0x04; 241 | } 242 | 243 | //Now we determine the two lattice points not part of the tetrahedron that may contribute. 244 | //This depends on the closest two tetrahedral vertices, including (0,0,0) 245 | double wins = 1 - inSum; 246 | if (wins > aScore || wins > bScore) { //(0,0,0) is one of the closest two tetrahedral vertices. 247 | byte c = (bScore > aScore ? bPoint : aPoint); //Our other closest vertex is the closest out of a and b. 248 | 249 | if ((c & 0x01) == 0) { 250 | xsv_ext0 = xsb - 1; 251 | xsv_ext1 = xsb; 252 | dx_ext0 = dx0 + 1; 253 | dx_ext1 = dx0; 254 | } else { 255 | xsv_ext0 = xsv_ext1 = xsb + 1; 256 | dx_ext0 = dx_ext1 = dx0 - 1; 257 | } 258 | 259 | if ((c & 0x02) == 0) { 260 | ysv_ext0 = ysv_ext1 = ysb; 261 | dy_ext0 = dy_ext1 = dy0; 262 | if ((c & 0x01) == 0) { 263 | ysv_ext1 -= 1; 264 | dy_ext1 += 1; 265 | } else { 266 | ysv_ext0 -= 1; 267 | dy_ext0 += 1; 268 | } 269 | } else { 270 | ysv_ext0 = ysv_ext1 = ysb + 1; 271 | dy_ext0 = dy_ext1 = dy0 - 1; 272 | } 273 | 274 | if ((c & 0x04) == 0) { 275 | zsv_ext0 = zsb; 276 | zsv_ext1 = zsb - 1; 277 | dz_ext0 = dz0; 278 | dz_ext1 = dz0 + 1; 279 | } else { 280 | zsv_ext0 = zsv_ext1 = zsb + 1; 281 | dz_ext0 = dz_ext1 = dz0 - 1; 282 | } 283 | } else { //(0,0,0) is not one of the closest two tetrahedral vertices. 284 | byte c = (byte)(aPoint | bPoint); //Our two extra vertices are determined by the closest two. 285 | 286 | if ((c & 0x01) == 0) { 287 | xsv_ext0 = xsb; 288 | xsv_ext1 = xsb - 1; 289 | dx_ext0 = dx0 - 2 * SQUISH_CONSTANT_3D; 290 | dx_ext1 = dx0 + 1 - SQUISH_CONSTANT_3D; 291 | } else { 292 | xsv_ext0 = xsv_ext1 = xsb + 1; 293 | dx_ext0 = dx0 - 1 - 2 * SQUISH_CONSTANT_3D; 294 | dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_3D; 295 | } 296 | 297 | if ((c & 0x02) == 0) { 298 | ysv_ext0 = ysb; 299 | ysv_ext1 = ysb - 1; 300 | dy_ext0 = dy0 - 2 * SQUISH_CONSTANT_3D; 301 | dy_ext1 = dy0 + 1 - SQUISH_CONSTANT_3D; 302 | } else { 303 | ysv_ext0 = ysv_ext1 = ysb + 1; 304 | dy_ext0 = dy0 - 1 - 2 * SQUISH_CONSTANT_3D; 305 | dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_3D; 306 | } 307 | 308 | if ((c & 0x04) == 0) { 309 | zsv_ext0 = zsb; 310 | zsv_ext1 = zsb - 1; 311 | dz_ext0 = dz0 - 2 * SQUISH_CONSTANT_3D; 312 | dz_ext1 = dz0 + 1 - SQUISH_CONSTANT_3D; 313 | } else { 314 | zsv_ext0 = zsv_ext1 = zsb + 1; 315 | dz_ext0 = dz0 - 1 - 2 * SQUISH_CONSTANT_3D; 316 | dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_3D; 317 | } 318 | } 319 | 320 | //Contribution (0,0,0) 321 | double attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0; 322 | if (attn0 > 0) { 323 | attn0 *= attn0; 324 | value += attn0 * attn0 * extrapolate(xsb + 0, ysb + 0, zsb + 0, dx0, dy0, dz0); 325 | } 326 | 327 | //Contribution (1,0,0) 328 | double dx1 = dx0 - 1 - SQUISH_CONSTANT_3D; 329 | double dy1 = dy0 - 0 - SQUISH_CONSTANT_3D; 330 | double dz1 = dz0 - 0 - SQUISH_CONSTANT_3D; 331 | double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1; 332 | if (attn1 > 0) { 333 | attn1 *= attn1; 334 | value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, zsb + 0, dx1, dy1, dz1); 335 | } 336 | 337 | //Contribution (0,1,0) 338 | double dx2 = dx0 - 0 - SQUISH_CONSTANT_3D; 339 | double dy2 = dy0 - 1 - SQUISH_CONSTANT_3D; 340 | double dz2 = dz1; 341 | double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2; 342 | if (attn2 > 0) { 343 | attn2 *= attn2; 344 | value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, zsb + 0, dx2, dy2, dz2); 345 | } 346 | 347 | //Contribution (0,0,1) 348 | double dx3 = dx2; 349 | double dy3 = dy1; 350 | double dz3 = dz0 - 1 - SQUISH_CONSTANT_3D; 351 | double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3; 352 | if (attn3 > 0) { 353 | attn3 *= attn3; 354 | value += attn3 * attn3 * extrapolate(xsb + 0, ysb + 0, zsb + 1, dx3, dy3, dz3); 355 | } 356 | } else if (inSum >= 2) { //We're inside the tetrahedron (3-Simplex) at (1,1,1) 357 | 358 | //Determine which two tetrahedral vertices are the closest, out of (1,1,0), (1,0,1), (0,1,1) but not (1,1,1). 359 | byte aPoint = 0x06; 360 | double aScore = xins; 361 | byte bPoint = 0x05; 362 | double bScore = yins; 363 | if (aScore <= bScore && zins < bScore) { 364 | bScore = zins; 365 | bPoint = 0x03; 366 | } else if (aScore > bScore && zins < aScore) { 367 | aScore = zins; 368 | aPoint = 0x03; 369 | } 370 | 371 | //Now we determine the two lattice points not part of the tetrahedron that may contribute. 372 | //This depends on the closest two tetrahedral vertices, including (1,1,1) 373 | double wins = 3 - inSum; 374 | if (wins < aScore || wins < bScore) { //(1,1,1) is one of the closest two tetrahedral vertices. 375 | byte c = (bScore < aScore ? bPoint : aPoint); //Our other closest vertex is the closest out of a and b. 376 | 377 | if ((c & 0x01) != 0) { 378 | xsv_ext0 = xsb + 2; 379 | xsv_ext1 = xsb + 1; 380 | dx_ext0 = dx0 - 2 - 3 * SQUISH_CONSTANT_3D; 381 | dx_ext1 = dx0 - 1 - 3 * SQUISH_CONSTANT_3D; 382 | } else { 383 | xsv_ext0 = xsv_ext1 = xsb; 384 | dx_ext0 = dx_ext1 = dx0 - 3 * SQUISH_CONSTANT_3D; 385 | } 386 | 387 | if ((c & 0x02) != 0) { 388 | ysv_ext0 = ysv_ext1 = ysb + 1; 389 | dy_ext0 = dy_ext1 = dy0 - 1 - 3 * SQUISH_CONSTANT_3D; 390 | if ((c & 0x01) != 0) { 391 | ysv_ext1 += 1; 392 | dy_ext1 -= 1; 393 | } else { 394 | ysv_ext0 += 1; 395 | dy_ext0 -= 1; 396 | } 397 | } else { 398 | ysv_ext0 = ysv_ext1 = ysb; 399 | dy_ext0 = dy_ext1 = dy0 - 3 * SQUISH_CONSTANT_3D; 400 | } 401 | 402 | if ((c & 0x04) != 0) { 403 | zsv_ext0 = zsb + 1; 404 | zsv_ext1 = zsb + 2; 405 | dz_ext0 = dz0 - 1 - 3 * SQUISH_CONSTANT_3D; 406 | dz_ext1 = dz0 - 2 - 3 * SQUISH_CONSTANT_3D; 407 | } else { 408 | zsv_ext0 = zsv_ext1 = zsb; 409 | dz_ext0 = dz_ext1 = dz0 - 3 * SQUISH_CONSTANT_3D; 410 | } 411 | } else { //(1,1,1) is not one of the closest two tetrahedral vertices. 412 | byte c = (byte)(aPoint & bPoint); //Our two extra vertices are determined by the closest two. 413 | 414 | if ((c & 0x01) != 0) { 415 | xsv_ext0 = xsb + 1; 416 | xsv_ext1 = xsb + 2; 417 | dx_ext0 = dx0 - 1 - SQUISH_CONSTANT_3D; 418 | dx_ext1 = dx0 - 2 - 2 * SQUISH_CONSTANT_3D; 419 | } else { 420 | xsv_ext0 = xsv_ext1 = xsb; 421 | dx_ext0 = dx0 - SQUISH_CONSTANT_3D; 422 | dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D; 423 | } 424 | 425 | if ((c & 0x02) != 0) { 426 | ysv_ext0 = ysb + 1; 427 | ysv_ext1 = ysb + 2; 428 | dy_ext0 = dy0 - 1 - SQUISH_CONSTANT_3D; 429 | dy_ext1 = dy0 - 2 - 2 * SQUISH_CONSTANT_3D; 430 | } else { 431 | ysv_ext0 = ysv_ext1 = ysb; 432 | dy_ext0 = dy0 - SQUISH_CONSTANT_3D; 433 | dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D; 434 | } 435 | 436 | if ((c & 0x04) != 0) { 437 | zsv_ext0 = zsb + 1; 438 | zsv_ext1 = zsb + 2; 439 | dz_ext0 = dz0 - 1 - SQUISH_CONSTANT_3D; 440 | dz_ext1 = dz0 - 2 - 2 * SQUISH_CONSTANT_3D; 441 | } else { 442 | zsv_ext0 = zsv_ext1 = zsb; 443 | dz_ext0 = dz0 - SQUISH_CONSTANT_3D; 444 | dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D; 445 | } 446 | } 447 | 448 | //Contribution (1,1,0) 449 | double dx3 = dx0 - 1 - 2 * SQUISH_CONSTANT_3D; 450 | double dy3 = dy0 - 1 - 2 * SQUISH_CONSTANT_3D; 451 | double dz3 = dz0 - 0 - 2 * SQUISH_CONSTANT_3D; 452 | double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3; 453 | if (attn3 > 0) { 454 | attn3 *= attn3; 455 | value += attn3 * attn3 * extrapolate(xsb + 1, ysb + 1, zsb + 0, dx3, dy3, dz3); 456 | } 457 | 458 | //Contribution (1,0,1) 459 | double dx2 = dx3; 460 | double dy2 = dy0 - 0 - 2 * SQUISH_CONSTANT_3D; 461 | double dz2 = dz0 - 1 - 2 * SQUISH_CONSTANT_3D; 462 | double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2; 463 | if (attn2 > 0) { 464 | attn2 *= attn2; 465 | value += attn2 * attn2 * extrapolate(xsb + 1, ysb + 0, zsb + 1, dx2, dy2, dz2); 466 | } 467 | 468 | //Contribution (0,1,1) 469 | double dx1 = dx0 - 0 - 2 * SQUISH_CONSTANT_3D; 470 | double dy1 = dy3; 471 | double dz1 = dz2; 472 | double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1; 473 | if (attn1 > 0) { 474 | attn1 *= attn1; 475 | value += attn1 * attn1 * extrapolate(xsb + 0, ysb + 1, zsb + 1, dx1, dy1, dz1); 476 | } 477 | 478 | //Contribution (1,1,1) 479 | dx0 = dx0 - 1 - 3 * SQUISH_CONSTANT_3D; 480 | dy0 = dy0 - 1 - 3 * SQUISH_CONSTANT_3D; 481 | dz0 = dz0 - 1 - 3 * SQUISH_CONSTANT_3D; 482 | double attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0; 483 | if (attn0 > 0) { 484 | attn0 *= attn0; 485 | value += attn0 * attn0 * extrapolate(xsb + 1, ysb + 1, zsb + 1, dx0, dy0, dz0); 486 | } 487 | } else { //We're inside the octahedron (Rectified 3-Simplex) in between. 488 | double aScore; 489 | byte aPoint; 490 | boolean aIsFurtherSide; 491 | double bScore; 492 | byte bPoint; 493 | boolean bIsFurtherSide; 494 | 495 | //Decide between point (0,0,1) and (1,1,0) as closest 496 | double p1 = xins + yins; 497 | if (p1 > 1) { 498 | aScore = p1 - 1; 499 | aPoint = 0x03; 500 | aIsFurtherSide = true; 501 | } else { 502 | aScore = 1 - p1; 503 | aPoint = 0x04; 504 | aIsFurtherSide = false; 505 | } 506 | 507 | //Decide between point (0,1,0) and (1,0,1) as closest 508 | double p2 = xins + zins; 509 | if (p2 > 1) { 510 | bScore = p2 - 1; 511 | bPoint = 0x05; 512 | bIsFurtherSide = true; 513 | } else { 514 | bScore = 1 - p2; 515 | bPoint = 0x02; 516 | bIsFurtherSide = false; 517 | } 518 | 519 | //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. 520 | double p3 = yins + zins; 521 | if (p3 > 1) { 522 | double score = p3 - 1; 523 | if (aScore <= bScore && aScore < score) { 524 | aScore = score; 525 | aPoint = 0x06; 526 | aIsFurtherSide = true; 527 | } else if (aScore > bScore && bScore < score) { 528 | bScore = score; 529 | bPoint = 0x06; 530 | bIsFurtherSide = true; 531 | } 532 | } else { 533 | double score = 1 - p3; 534 | if (aScore <= bScore && aScore < score) { 535 | aScore = score; 536 | aPoint = 0x01; 537 | aIsFurtherSide = false; 538 | } else if (aScore > bScore && bScore < score) { 539 | bScore = score; 540 | bPoint = 0x01; 541 | bIsFurtherSide = false; 542 | } 543 | } 544 | 545 | //Where each of the two closest points are determines how the extra two vertices are calculated. 546 | if (aIsFurtherSide == bIsFurtherSide) { 547 | if (aIsFurtherSide) { //Both closest points on (1,1,1) side 548 | 549 | //One of the two extra points is (1,1,1) 550 | dx_ext0 = dx0 - 1 - 3 * SQUISH_CONSTANT_3D; 551 | dy_ext0 = dy0 - 1 - 3 * SQUISH_CONSTANT_3D; 552 | dz_ext0 = dz0 - 1 - 3 * SQUISH_CONSTANT_3D; 553 | xsv_ext0 = xsb + 1; 554 | ysv_ext0 = ysb + 1; 555 | zsv_ext0 = zsb + 1; 556 | 557 | //Other extra point is based on the shared axis. 558 | byte c = (byte)(aPoint & bPoint); 559 | if ((c & 0x01) != 0) { 560 | dx_ext1 = dx0 - 2 - 2 * SQUISH_CONSTANT_3D; 561 | dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D; 562 | dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D; 563 | xsv_ext1 = xsb + 2; 564 | ysv_ext1 = ysb; 565 | zsv_ext1 = zsb; 566 | } else if ((c & 0x02) != 0) { 567 | dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D; 568 | dy_ext1 = dy0 - 2 - 2 * SQUISH_CONSTANT_3D; 569 | dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D; 570 | xsv_ext1 = xsb; 571 | ysv_ext1 = ysb + 2; 572 | zsv_ext1 = zsb; 573 | } else { 574 | dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D; 575 | dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D; 576 | dz_ext1 = dz0 - 2 - 2 * SQUISH_CONSTANT_3D; 577 | xsv_ext1 = xsb; 578 | ysv_ext1 = ysb; 579 | zsv_ext1 = zsb + 2; 580 | } 581 | } else {//Both closest points on (0,0,0) side 582 | 583 | //One of the two extra points is (0,0,0) 584 | dx_ext0 = dx0; 585 | dy_ext0 = dy0; 586 | dz_ext0 = dz0; 587 | xsv_ext0 = xsb; 588 | ysv_ext0 = ysb; 589 | zsv_ext0 = zsb; 590 | 591 | //Other extra point is based on the omitted axis. 592 | byte c = (byte)(aPoint | bPoint); 593 | if ((c & 0x01) == 0) { 594 | dx_ext1 = dx0 + 1 - SQUISH_CONSTANT_3D; 595 | dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_3D; 596 | dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_3D; 597 | xsv_ext1 = xsb - 1; 598 | ysv_ext1 = ysb + 1; 599 | zsv_ext1 = zsb + 1; 600 | } else if ((c & 0x02) == 0) { 601 | dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_3D; 602 | dy_ext1 = dy0 + 1 - SQUISH_CONSTANT_3D; 603 | dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_3D; 604 | xsv_ext1 = xsb + 1; 605 | ysv_ext1 = ysb - 1; 606 | zsv_ext1 = zsb + 1; 607 | } else { 608 | dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_3D; 609 | dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_3D; 610 | dz_ext1 = dz0 + 1 - SQUISH_CONSTANT_3D; 611 | xsv_ext1 = xsb + 1; 612 | ysv_ext1 = ysb + 1; 613 | zsv_ext1 = zsb - 1; 614 | } 615 | } 616 | } else { //One point on (0,0,0) side, one point on (1,1,1) side 617 | byte c1, c2; 618 | if (aIsFurtherSide) { 619 | c1 = aPoint; 620 | c2 = bPoint; 621 | } else { 622 | c1 = bPoint; 623 | c2 = aPoint; 624 | } 625 | 626 | //One contribution is a permutation of (1,1,-1) 627 | if ((c1 & 0x01) == 0) { 628 | dx_ext0 = dx0 + 1 - SQUISH_CONSTANT_3D; 629 | dy_ext0 = dy0 - 1 - SQUISH_CONSTANT_3D; 630 | dz_ext0 = dz0 - 1 - SQUISH_CONSTANT_3D; 631 | xsv_ext0 = xsb - 1; 632 | ysv_ext0 = ysb + 1; 633 | zsv_ext0 = zsb + 1; 634 | } else if ((c1 & 0x02) == 0) { 635 | dx_ext0 = dx0 - 1 - SQUISH_CONSTANT_3D; 636 | dy_ext0 = dy0 + 1 - SQUISH_CONSTANT_3D; 637 | dz_ext0 = dz0 - 1 - SQUISH_CONSTANT_3D; 638 | xsv_ext0 = xsb + 1; 639 | ysv_ext0 = ysb - 1; 640 | zsv_ext0 = zsb + 1; 641 | } else { 642 | dx_ext0 = dx0 - 1 - SQUISH_CONSTANT_3D; 643 | dy_ext0 = dy0 - 1 - SQUISH_CONSTANT_3D; 644 | dz_ext0 = dz0 + 1 - SQUISH_CONSTANT_3D; 645 | xsv_ext0 = xsb + 1; 646 | ysv_ext0 = ysb + 1; 647 | zsv_ext0 = zsb - 1; 648 | } 649 | 650 | //One contribution is a permutation of (0,0,2) 651 | dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D; 652 | dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D; 653 | dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D; 654 | xsv_ext1 = xsb; 655 | ysv_ext1 = ysb; 656 | zsv_ext1 = zsb; 657 | if ((c2 & 0x01) != 0) { 658 | dx_ext1 -= 2; 659 | xsv_ext1 += 2; 660 | } else if ((c2 & 0x02) != 0) { 661 | dy_ext1 -= 2; 662 | ysv_ext1 += 2; 663 | } else { 664 | dz_ext1 -= 2; 665 | zsv_ext1 += 2; 666 | } 667 | } 668 | 669 | //Contribution (1,0,0) 670 | double dx1 = dx0 - 1 - SQUISH_CONSTANT_3D; 671 | double dy1 = dy0 - 0 - SQUISH_CONSTANT_3D; 672 | double dz1 = dz0 - 0 - SQUISH_CONSTANT_3D; 673 | double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1; 674 | if (attn1 > 0) { 675 | attn1 *= attn1; 676 | value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, zsb + 0, dx1, dy1, dz1); 677 | } 678 | 679 | //Contribution (0,1,0) 680 | double dx2 = dx0 - 0 - SQUISH_CONSTANT_3D; 681 | double dy2 = dy0 - 1 - SQUISH_CONSTANT_3D; 682 | double dz2 = dz1; 683 | double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2; 684 | if (attn2 > 0) { 685 | attn2 *= attn2; 686 | value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, zsb + 0, dx2, dy2, dz2); 687 | } 688 | 689 | //Contribution (0,0,1) 690 | double dx3 = dx2; 691 | double dy3 = dy1; 692 | double dz3 = dz0 - 1 - SQUISH_CONSTANT_3D; 693 | double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3; 694 | if (attn3 > 0) { 695 | attn3 *= attn3; 696 | value += attn3 * attn3 * extrapolate(xsb + 0, ysb + 0, zsb + 1, dx3, dy3, dz3); 697 | } 698 | 699 | //Contribution (1,1,0) 700 | double dx4 = dx0 - 1 - 2 * SQUISH_CONSTANT_3D; 701 | double dy4 = dy0 - 1 - 2 * SQUISH_CONSTANT_3D; 702 | double dz4 = dz0 - 0 - 2 * SQUISH_CONSTANT_3D; 703 | double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4; 704 | if (attn4 > 0) { 705 | attn4 *= attn4; 706 | value += attn4 * attn4 * extrapolate(xsb + 1, ysb + 1, zsb + 0, dx4, dy4, dz4); 707 | } 708 | 709 | //Contribution (1,0,1) 710 | double dx5 = dx4; 711 | double dy5 = dy0 - 0 - 2 * SQUISH_CONSTANT_3D; 712 | double dz5 = dz0 - 1 - 2 * SQUISH_CONSTANT_3D; 713 | double attn5 = 2 - dx5 * dx5 - dy5 * dy5 - dz5 * dz5; 714 | if (attn5 > 0) { 715 | attn5 *= attn5; 716 | value += attn5 * attn5 * extrapolate(xsb + 1, ysb + 0, zsb + 1, dx5, dy5, dz5); 717 | } 718 | 719 | //Contribution (0,1,1) 720 | double dx6 = dx0 - 0 - 2 * SQUISH_CONSTANT_3D; 721 | double dy6 = dy4; 722 | double dz6 = dz5; 723 | double attn6 = 2 - dx6 * dx6 - dy6 * dy6 - dz6 * dz6; 724 | if (attn6 > 0) { 725 | attn6 *= attn6; 726 | value += attn6 * attn6 * extrapolate(xsb + 0, ysb + 1, zsb + 1, dx6, dy6, dz6); 727 | } 728 | } 729 | 730 | //First extra vertex 731 | double attn_ext0 = 2 - dx_ext0 * dx_ext0 - dy_ext0 * dy_ext0 - dz_ext0 * dz_ext0; 732 | if (attn_ext0 > 0) 733 | { 734 | attn_ext0 *= attn_ext0; 735 | value += attn_ext0 * attn_ext0 * extrapolate(xsv_ext0, ysv_ext0, zsv_ext0, dx_ext0, dy_ext0, dz_ext0); 736 | } 737 | 738 | //Second extra vertex 739 | double attn_ext1 = 2 - dx_ext1 * dx_ext1 - dy_ext1 * dy_ext1 - dz_ext1 * dz_ext1; 740 | if (attn_ext1 > 0) 741 | { 742 | attn_ext1 *= attn_ext1; 743 | value += attn_ext1 * attn_ext1 * extrapolate(xsv_ext1, ysv_ext1, zsv_ext1, dx_ext1, dy_ext1, dz_ext1); 744 | } 745 | 746 | return value / NORM_CONSTANT_3D; 747 | } 748 | 749 | //4D OpenSimplex Noise. 750 | public double eval(double x, double y, double z, double w) { 751 | 752 | //Place input coordinates on simplectic honeycomb. 753 | double stretchOffset = (x + y + z + w) * STRETCH_CONSTANT_4D; 754 | double xs = x + stretchOffset; 755 | double ys = y + stretchOffset; 756 | double zs = z + stretchOffset; 757 | double ws = w + stretchOffset; 758 | 759 | //Floor to get simplectic honeycomb coordinates of rhombo-hypercube super-cell origin. 760 | int xsb = fastFloor(xs); 761 | int ysb = fastFloor(ys); 762 | int zsb = fastFloor(zs); 763 | int wsb = fastFloor(ws); 764 | 765 | //Skew out to get actual coordinates of stretched rhombo-hypercube origin. We'll need these later. 766 | double squishOffset = (xsb + ysb + zsb + wsb) * SQUISH_CONSTANT_4D; 767 | double xb = xsb + squishOffset; 768 | double yb = ysb + squishOffset; 769 | double zb = zsb + squishOffset; 770 | double wb = wsb + squishOffset; 771 | 772 | //Compute simplectic honeycomb coordinates relative to rhombo-hypercube origin. 773 | double xins = xs - xsb; 774 | double yins = ys - ysb; 775 | double zins = zs - zsb; 776 | double wins = ws - wsb; 777 | 778 | //Sum those together to get a value that determines which region we're in. 779 | double inSum = xins + yins + zins + wins; 780 | 781 | //Positions relative to origin point. 782 | double dx0 = x - xb; 783 | double dy0 = y - yb; 784 | double dz0 = z - zb; 785 | double dw0 = w - wb; 786 | 787 | //We'll be defining these inside the next block and using them afterwards. 788 | double dx_ext0, dy_ext0, dz_ext0, dw_ext0; 789 | double dx_ext1, dy_ext1, dz_ext1, dw_ext1; 790 | double dx_ext2, dy_ext2, dz_ext2, dw_ext2; 791 | int xsv_ext0, ysv_ext0, zsv_ext0, wsv_ext0; 792 | int xsv_ext1, ysv_ext1, zsv_ext1, wsv_ext1; 793 | int xsv_ext2, ysv_ext2, zsv_ext2, wsv_ext2; 794 | 795 | double value = 0; 796 | if (inSum <= 1) { //We're inside the pentachoron (4-Simplex) at (0,0,0,0) 797 | 798 | //Determine which two of (0,0,0,1), (0,0,1,0), (0,1,0,0), (1,0,0,0) are closest. 799 | byte aPoint = 0x01; 800 | double aScore = xins; 801 | byte bPoint = 0x02; 802 | double bScore = yins; 803 | if (aScore >= bScore && zins > bScore) { 804 | bScore = zins; 805 | bPoint = 0x04; 806 | } else if (aScore < bScore && zins > aScore) { 807 | aScore = zins; 808 | aPoint = 0x04; 809 | } 810 | if (aScore >= bScore && wins > bScore) { 811 | bScore = wins; 812 | bPoint = 0x08; 813 | } else if (aScore < bScore && wins > aScore) { 814 | aScore = wins; 815 | aPoint = 0x08; 816 | } 817 | 818 | //Now we determine the three lattice points not part of the pentachoron that may contribute. 819 | //This depends on the closest two pentachoron vertices, including (0,0,0,0) 820 | double uins = 1 - inSum; 821 | if (uins > aScore || uins > bScore) { //(0,0,0,0) is one of the closest two pentachoron vertices. 822 | byte c = (bScore > aScore ? bPoint : aPoint); //Our other closest vertex is the closest out of a and b. 823 | if ((c & 0x01) == 0) { 824 | xsv_ext0 = xsb - 1; 825 | xsv_ext1 = xsv_ext2 = xsb; 826 | dx_ext0 = dx0 + 1; 827 | dx_ext1 = dx_ext2 = dx0; 828 | } else { 829 | xsv_ext0 = xsv_ext1 = xsv_ext2 = xsb + 1; 830 | dx_ext0 = dx_ext1 = dx_ext2 = dx0 - 1; 831 | } 832 | 833 | if ((c & 0x02) == 0) { 834 | ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb; 835 | dy_ext0 = dy_ext1 = dy_ext2 = dy0; 836 | if ((c & 0x01) == 0x01) { 837 | ysv_ext0 -= 1; 838 | dy_ext0 += 1; 839 | } else { 840 | ysv_ext1 -= 1; 841 | dy_ext1 += 1; 842 | } 843 | } else { 844 | ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb + 1; 845 | dy_ext0 = dy_ext1 = dy_ext2 = dy0 - 1; 846 | } 847 | 848 | if ((c & 0x04) == 0) { 849 | zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb; 850 | dz_ext0 = dz_ext1 = dz_ext2 = dz0; 851 | if ((c & 0x03) != 0) { 852 | if ((c & 0x03) == 0x03) { 853 | zsv_ext0 -= 1; 854 | dz_ext0 += 1; 855 | } else { 856 | zsv_ext1 -= 1; 857 | dz_ext1 += 1; 858 | } 859 | } else { 860 | zsv_ext2 -= 1; 861 | dz_ext2 += 1; 862 | } 863 | } else { 864 | zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb + 1; 865 | dz_ext0 = dz_ext1 = dz_ext2 = dz0 - 1; 866 | } 867 | 868 | if ((c & 0x08) == 0) { 869 | wsv_ext0 = wsv_ext1 = wsb; 870 | wsv_ext2 = wsb - 1; 871 | dw_ext0 = dw_ext1 = dw0; 872 | dw_ext2 = dw0 + 1; 873 | } else { 874 | wsv_ext0 = wsv_ext1 = wsv_ext2 = wsb + 1; 875 | dw_ext0 = dw_ext1 = dw_ext2 = dw0 - 1; 876 | } 877 | } else { //(0,0,0,0) is not one of the closest two pentachoron vertices. 878 | byte c = (byte)(aPoint | bPoint); //Our three extra vertices are determined by the closest two. 879 | 880 | if ((c & 0x01) == 0) { 881 | xsv_ext0 = xsv_ext2 = xsb; 882 | xsv_ext1 = xsb - 1; 883 | dx_ext0 = dx0 - 2 * SQUISH_CONSTANT_4D; 884 | dx_ext1 = dx0 + 1 - SQUISH_CONSTANT_4D; 885 | dx_ext2 = dx0 - SQUISH_CONSTANT_4D; 886 | } else { 887 | xsv_ext0 = xsv_ext1 = xsv_ext2 = xsb + 1; 888 | dx_ext0 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; 889 | dx_ext1 = dx_ext2 = dx0 - 1 - SQUISH_CONSTANT_4D; 890 | } 891 | 892 | if ((c & 0x02) == 0) { 893 | ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb; 894 | dy_ext0 = dy0 - 2 * SQUISH_CONSTANT_4D; 895 | dy_ext1 = dy_ext2 = dy0 - SQUISH_CONSTANT_4D; 896 | if ((c & 0x01) == 0x01) { 897 | ysv_ext1 -= 1; 898 | dy_ext1 += 1; 899 | } else { 900 | ysv_ext2 -= 1; 901 | dy_ext2 += 1; 902 | } 903 | } else { 904 | ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb + 1; 905 | dy_ext0 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; 906 | dy_ext1 = dy_ext2 = dy0 - 1 - SQUISH_CONSTANT_4D; 907 | } 908 | 909 | if ((c & 0x04) == 0) { 910 | zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb; 911 | dz_ext0 = dz0 - 2 * SQUISH_CONSTANT_4D; 912 | dz_ext1 = dz_ext2 = dz0 - SQUISH_CONSTANT_4D; 913 | if ((c & 0x03) == 0x03) { 914 | zsv_ext1 -= 1; 915 | dz_ext1 += 1; 916 | } else { 917 | zsv_ext2 -= 1; 918 | dz_ext2 += 1; 919 | } 920 | } else { 921 | zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb + 1; 922 | dz_ext0 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; 923 | dz_ext1 = dz_ext2 = dz0 - 1 - SQUISH_CONSTANT_4D; 924 | } 925 | 926 | if ((c & 0x08) == 0) { 927 | wsv_ext0 = wsv_ext1 = wsb; 928 | wsv_ext2 = wsb - 1; 929 | dw_ext0 = dw0 - 2 * SQUISH_CONSTANT_4D; 930 | dw_ext1 = dw0 - SQUISH_CONSTANT_4D; 931 | dw_ext2 = dw0 + 1 - SQUISH_CONSTANT_4D; 932 | } else { 933 | wsv_ext0 = wsv_ext1 = wsv_ext2 = wsb + 1; 934 | dw_ext0 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; 935 | dw_ext1 = dw_ext2 = dw0 - 1 - SQUISH_CONSTANT_4D; 936 | } 937 | } 938 | 939 | //Contribution (0,0,0,0) 940 | double attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0 - dw0 * dw0; 941 | if (attn0 > 0) { 942 | attn0 *= attn0; 943 | value += attn0 * attn0 * extrapolate(xsb + 0, ysb + 0, zsb + 0, wsb + 0, dx0, dy0, dz0, dw0); 944 | } 945 | 946 | //Contribution (1,0,0,0) 947 | double dx1 = dx0 - 1 - SQUISH_CONSTANT_4D; 948 | double dy1 = dy0 - 0 - SQUISH_CONSTANT_4D; 949 | double dz1 = dz0 - 0 - SQUISH_CONSTANT_4D; 950 | double dw1 = dw0 - 0 - SQUISH_CONSTANT_4D; 951 | double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1 - dw1 * dw1; 952 | if (attn1 > 0) { 953 | attn1 *= attn1; 954 | value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, zsb + 0, wsb + 0, dx1, dy1, dz1, dw1); 955 | } 956 | 957 | //Contribution (0,1,0,0) 958 | double dx2 = dx0 - 0 - SQUISH_CONSTANT_4D; 959 | double dy2 = dy0 - 1 - SQUISH_CONSTANT_4D; 960 | double dz2 = dz1; 961 | double dw2 = dw1; 962 | double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2 - dw2 * dw2; 963 | if (attn2 > 0) { 964 | attn2 *= attn2; 965 | value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, zsb + 0, wsb + 0, dx2, dy2, dz2, dw2); 966 | } 967 | 968 | //Contribution (0,0,1,0) 969 | double dx3 = dx2; 970 | double dy3 = dy1; 971 | double dz3 = dz0 - 1 - SQUISH_CONSTANT_4D; 972 | double dw3 = dw1; 973 | double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3 - dw3 * dw3; 974 | if (attn3 > 0) { 975 | attn3 *= attn3; 976 | value += attn3 * attn3 * extrapolate(xsb + 0, ysb + 0, zsb + 1, wsb + 0, dx3, dy3, dz3, dw3); 977 | } 978 | 979 | //Contribution (0,0,0,1) 980 | double dx4 = dx2; 981 | double dy4 = dy1; 982 | double dz4 = dz1; 983 | double dw4 = dw0 - 1 - SQUISH_CONSTANT_4D; 984 | double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4 - dw4 * dw4; 985 | if (attn4 > 0) { 986 | attn4 *= attn4; 987 | value += attn4 * attn4 * extrapolate(xsb + 0, ysb + 0, zsb + 0, wsb + 1, dx4, dy4, dz4, dw4); 988 | } 989 | } else if (inSum >= 3) { //We're inside the pentachoron (4-Simplex) at (1,1,1,1) 990 | //Determine which two of (1,1,1,0), (1,1,0,1), (1,0,1,1), (0,1,1,1) are closest. 991 | byte aPoint = 0x0E; 992 | double aScore = xins; 993 | byte bPoint = 0x0D; 994 | double bScore = yins; 995 | if (aScore <= bScore && zins < bScore) { 996 | bScore = zins; 997 | bPoint = 0x0B; 998 | } else if (aScore > bScore && zins < aScore) { 999 | aScore = zins; 1000 | aPoint = 0x0B; 1001 | } 1002 | if (aScore <= bScore && wins < bScore) { 1003 | bScore = wins; 1004 | bPoint = 0x07; 1005 | } else if (aScore > bScore && wins < aScore) { 1006 | aScore = wins; 1007 | aPoint = 0x07; 1008 | } 1009 | 1010 | //Now we determine the three lattice points not part of the pentachoron that may contribute. 1011 | //This depends on the closest two pentachoron vertices, including (0,0,0,0) 1012 | double uins = 4 - inSum; 1013 | if (uins < aScore || uins < bScore) { //(1,1,1,1) is one of the closest two pentachoron vertices. 1014 | byte c = (bScore < aScore ? bPoint : aPoint); //Our other closest vertex is the closest out of a and b. 1015 | 1016 | if ((c & 0x01) != 0) { 1017 | xsv_ext0 = xsb + 2; 1018 | xsv_ext1 = xsv_ext2 = xsb + 1; 1019 | dx_ext0 = dx0 - 2 - 4 * SQUISH_CONSTANT_4D; 1020 | dx_ext1 = dx_ext2 = dx0 - 1 - 4 * SQUISH_CONSTANT_4D; 1021 | } else { 1022 | xsv_ext0 = xsv_ext1 = xsv_ext2 = xsb; 1023 | dx_ext0 = dx_ext1 = dx_ext2 = dx0 - 4 * SQUISH_CONSTANT_4D; 1024 | } 1025 | 1026 | if ((c & 0x02) != 0) { 1027 | ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb + 1; 1028 | dy_ext0 = dy_ext1 = dy_ext2 = dy0 - 1 - 4 * SQUISH_CONSTANT_4D; 1029 | if ((c & 0x01) != 0) { 1030 | ysv_ext1 += 1; 1031 | dy_ext1 -= 1; 1032 | } else { 1033 | ysv_ext0 += 1; 1034 | dy_ext0 -= 1; 1035 | } 1036 | } else { 1037 | ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb; 1038 | dy_ext0 = dy_ext1 = dy_ext2 = dy0 - 4 * SQUISH_CONSTANT_4D; 1039 | } 1040 | 1041 | if ((c & 0x04) != 0) { 1042 | zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb + 1; 1043 | dz_ext0 = dz_ext1 = dz_ext2 = dz0 - 1 - 4 * SQUISH_CONSTANT_4D; 1044 | if ((c & 0x03) != 0x03) { 1045 | if ((c & 0x03) == 0) { 1046 | zsv_ext0 += 1; 1047 | dz_ext0 -= 1; 1048 | } else { 1049 | zsv_ext1 += 1; 1050 | dz_ext1 -= 1; 1051 | } 1052 | } else { 1053 | zsv_ext2 += 1; 1054 | dz_ext2 -= 1; 1055 | } 1056 | } else { 1057 | zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb; 1058 | dz_ext0 = dz_ext1 = dz_ext2 = dz0 - 4 * SQUISH_CONSTANT_4D; 1059 | } 1060 | 1061 | if ((c & 0x08) != 0) { 1062 | wsv_ext0 = wsv_ext1 = wsb + 1; 1063 | wsv_ext2 = wsb + 2; 1064 | dw_ext0 = dw_ext1 = dw0 - 1 - 4 * SQUISH_CONSTANT_4D; 1065 | dw_ext2 = dw0 - 2 - 4 * SQUISH_CONSTANT_4D; 1066 | } else { 1067 | wsv_ext0 = wsv_ext1 = wsv_ext2 = wsb; 1068 | dw_ext0 = dw_ext1 = dw_ext2 = dw0 - 4 * SQUISH_CONSTANT_4D; 1069 | } 1070 | } else { //(1,1,1,1) is not one of the closest two pentachoron vertices. 1071 | byte c = (byte)(aPoint & bPoint); //Our three extra vertices are determined by the closest two. 1072 | 1073 | if ((c & 0x01) != 0) { 1074 | xsv_ext0 = xsv_ext2 = xsb + 1; 1075 | xsv_ext1 = xsb + 2; 1076 | dx_ext0 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; 1077 | dx_ext1 = dx0 - 2 - 3 * SQUISH_CONSTANT_4D; 1078 | dx_ext2 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D; 1079 | } else { 1080 | xsv_ext0 = xsv_ext1 = xsv_ext2 = xsb; 1081 | dx_ext0 = dx0 - 2 * SQUISH_CONSTANT_4D; 1082 | dx_ext1 = dx_ext2 = dx0 - 3 * SQUISH_CONSTANT_4D; 1083 | } 1084 | 1085 | if ((c & 0x02) != 0) { 1086 | ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb + 1; 1087 | dy_ext0 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; 1088 | dy_ext1 = dy_ext2 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D; 1089 | if ((c & 0x01) != 0) { 1090 | ysv_ext2 += 1; 1091 | dy_ext2 -= 1; 1092 | } else { 1093 | ysv_ext1 += 1; 1094 | dy_ext1 -= 1; 1095 | } 1096 | } else { 1097 | ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb; 1098 | dy_ext0 = dy0 - 2 * SQUISH_CONSTANT_4D; 1099 | dy_ext1 = dy_ext2 = dy0 - 3 * SQUISH_CONSTANT_4D; 1100 | } 1101 | 1102 | if ((c & 0x04) != 0) { 1103 | zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb + 1; 1104 | dz_ext0 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; 1105 | dz_ext1 = dz_ext2 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D; 1106 | if ((c & 0x03) != 0) { 1107 | zsv_ext2 += 1; 1108 | dz_ext2 -= 1; 1109 | } else { 1110 | zsv_ext1 += 1; 1111 | dz_ext1 -= 1; 1112 | } 1113 | } else { 1114 | zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb; 1115 | dz_ext0 = dz0 - 2 * SQUISH_CONSTANT_4D; 1116 | dz_ext1 = dz_ext2 = dz0 - 3 * SQUISH_CONSTANT_4D; 1117 | } 1118 | 1119 | if ((c & 0x08) != 0) { 1120 | wsv_ext0 = wsv_ext1 = wsb + 1; 1121 | wsv_ext2 = wsb + 2; 1122 | dw_ext0 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; 1123 | dw_ext1 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D; 1124 | dw_ext2 = dw0 - 2 - 3 * SQUISH_CONSTANT_4D; 1125 | } else { 1126 | wsv_ext0 = wsv_ext1 = wsv_ext2 = wsb; 1127 | dw_ext0 = dw0 - 2 * SQUISH_CONSTANT_4D; 1128 | dw_ext1 = dw_ext2 = dw0 - 3 * SQUISH_CONSTANT_4D; 1129 | } 1130 | } 1131 | 1132 | //Contribution (1,1,1,0) 1133 | double dx4 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D; 1134 | double dy4 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D; 1135 | double dz4 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D; 1136 | double dw4 = dw0 - 3 * SQUISH_CONSTANT_4D; 1137 | double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4 - dw4 * dw4; 1138 | if (attn4 > 0) { 1139 | attn4 *= attn4; 1140 | value += attn4 * attn4 * extrapolate(xsb + 1, ysb + 1, zsb + 1, wsb + 0, dx4, dy4, dz4, dw4); 1141 | } 1142 | 1143 | //Contribution (1,1,0,1) 1144 | double dx3 = dx4; 1145 | double dy3 = dy4; 1146 | double dz3 = dz0 - 3 * SQUISH_CONSTANT_4D; 1147 | double dw3 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D; 1148 | double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3 - dw3 * dw3; 1149 | if (attn3 > 0) { 1150 | attn3 *= attn3; 1151 | value += attn3 * attn3 * extrapolate(xsb + 1, ysb + 1, zsb + 0, wsb + 1, dx3, dy3, dz3, dw3); 1152 | } 1153 | 1154 | //Contribution (1,0,1,1) 1155 | double dx2 = dx4; 1156 | double dy2 = dy0 - 3 * SQUISH_CONSTANT_4D; 1157 | double dz2 = dz4; 1158 | double dw2 = dw3; 1159 | double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2 - dw2 * dw2; 1160 | if (attn2 > 0) { 1161 | attn2 *= attn2; 1162 | value += attn2 * attn2 * extrapolate(xsb + 1, ysb + 0, zsb + 1, wsb + 1, dx2, dy2, dz2, dw2); 1163 | } 1164 | 1165 | //Contribution (0,1,1,1) 1166 | double dx1 = dx0 - 3 * SQUISH_CONSTANT_4D; 1167 | double dz1 = dz4; 1168 | double dy1 = dy4; 1169 | double dw1 = dw3; 1170 | double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1 - dw1 * dw1; 1171 | if (attn1 > 0) { 1172 | attn1 *= attn1; 1173 | value += attn1 * attn1 * extrapolate(xsb + 0, ysb + 1, zsb + 1, wsb + 1, dx1, dy1, dz1, dw1); 1174 | } 1175 | 1176 | //Contribution (1,1,1,1) 1177 | dx0 = dx0 - 1 - 4 * SQUISH_CONSTANT_4D; 1178 | dy0 = dy0 - 1 - 4 * SQUISH_CONSTANT_4D; 1179 | dz0 = dz0 - 1 - 4 * SQUISH_CONSTANT_4D; 1180 | dw0 = dw0 - 1 - 4 * SQUISH_CONSTANT_4D; 1181 | double attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0 - dw0 * dw0; 1182 | if (attn0 > 0) { 1183 | attn0 *= attn0; 1184 | value += attn0 * attn0 * extrapolate(xsb + 1, ysb + 1, zsb + 1, wsb + 1, dx0, dy0, dz0, dw0); 1185 | } 1186 | } else if (inSum <= 2) { //We're inside the first dispentachoron (Rectified 4-Simplex) 1187 | double aScore; 1188 | byte aPoint; 1189 | boolean aIsBiggerSide = true; 1190 | double bScore; 1191 | byte bPoint; 1192 | boolean bIsBiggerSide = true; 1193 | 1194 | //Decide between (1,1,0,0) and (0,0,1,1) 1195 | if (xins + yins > zins + wins) { 1196 | aScore = xins + yins; 1197 | aPoint = 0x03; 1198 | } else { 1199 | aScore = zins + wins; 1200 | aPoint = 0x0C; 1201 | } 1202 | 1203 | //Decide between (1,0,1,0) and (0,1,0,1) 1204 | if (xins + zins > yins + wins) { 1205 | bScore = xins + zins; 1206 | bPoint = 0x05; 1207 | } else { 1208 | bScore = yins + wins; 1209 | bPoint = 0x0A; 1210 | } 1211 | 1212 | //Closer between (1,0,0,1) and (0,1,1,0) will replace the further of a and b, if closer. 1213 | if (xins + wins > yins + zins) { 1214 | double score = xins + wins; 1215 | if (aScore >= bScore && score > bScore) { 1216 | bScore = score; 1217 | bPoint = 0x09; 1218 | } else if (aScore < bScore && score > aScore) { 1219 | aScore = score; 1220 | aPoint = 0x09; 1221 | } 1222 | } else { 1223 | double score = yins + zins; 1224 | if (aScore >= bScore && score > bScore) { 1225 | bScore = score; 1226 | bPoint = 0x06; 1227 | } else if (aScore < bScore && score > aScore) { 1228 | aScore = score; 1229 | aPoint = 0x06; 1230 | } 1231 | } 1232 | 1233 | //Decide if (1,0,0,0) is closer. 1234 | double p1 = 2 - inSum + xins; 1235 | if (aScore >= bScore && p1 > bScore) { 1236 | bScore = p1; 1237 | bPoint = 0x01; 1238 | bIsBiggerSide = false; 1239 | } else if (aScore < bScore && p1 > aScore) { 1240 | aScore = p1; 1241 | aPoint = 0x01; 1242 | aIsBiggerSide = false; 1243 | } 1244 | 1245 | //Decide if (0,1,0,0) is closer. 1246 | double p2 = 2 - inSum + yins; 1247 | if (aScore >= bScore && p2 > bScore) { 1248 | bScore = p2; 1249 | bPoint = 0x02; 1250 | bIsBiggerSide = false; 1251 | } else if (aScore < bScore && p2 > aScore) { 1252 | aScore = p2; 1253 | aPoint = 0x02; 1254 | aIsBiggerSide = false; 1255 | } 1256 | 1257 | //Decide if (0,0,1,0) is closer. 1258 | double p3 = 2 - inSum + zins; 1259 | if (aScore >= bScore && p3 > bScore) { 1260 | bScore = p3; 1261 | bPoint = 0x04; 1262 | bIsBiggerSide = false; 1263 | } else if (aScore < bScore && p3 > aScore) { 1264 | aScore = p3; 1265 | aPoint = 0x04; 1266 | aIsBiggerSide = false; 1267 | } 1268 | 1269 | //Decide if (0,0,0,1) is closer. 1270 | double p4 = 2 - inSum + wins; 1271 | if (aScore >= bScore && p4 > bScore) { 1272 | bScore = p4; 1273 | bPoint = 0x08; 1274 | bIsBiggerSide = false; 1275 | } else if (aScore < bScore && p4 > aScore) { 1276 | aScore = p4; 1277 | aPoint = 0x08; 1278 | aIsBiggerSide = false; 1279 | } 1280 | 1281 | //Where each of the two closest points are determines how the extra three vertices are calculated. 1282 | if (aIsBiggerSide == bIsBiggerSide) { 1283 | if (aIsBiggerSide) { //Both closest points on the bigger side 1284 | byte c1 = (byte)(aPoint | bPoint); 1285 | byte c2 = (byte)(aPoint & bPoint); 1286 | if ((c1 & 0x01) == 0) { 1287 | xsv_ext0 = xsb; 1288 | xsv_ext1 = xsb - 1; 1289 | dx_ext0 = dx0 - 3 * SQUISH_CONSTANT_4D; 1290 | dx_ext1 = dx0 + 1 - 2 * SQUISH_CONSTANT_4D; 1291 | } else { 1292 | xsv_ext0 = xsv_ext1 = xsb + 1; 1293 | dx_ext0 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D; 1294 | dx_ext1 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; 1295 | } 1296 | 1297 | if ((c1 & 0x02) == 0) { 1298 | ysv_ext0 = ysb; 1299 | ysv_ext1 = ysb - 1; 1300 | dy_ext0 = dy0 - 3 * SQUISH_CONSTANT_4D; 1301 | dy_ext1 = dy0 + 1 - 2 * SQUISH_CONSTANT_4D; 1302 | } else { 1303 | ysv_ext0 = ysv_ext1 = ysb + 1; 1304 | dy_ext0 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D; 1305 | dy_ext1 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; 1306 | } 1307 | 1308 | if ((c1 & 0x04) == 0) { 1309 | zsv_ext0 = zsb; 1310 | zsv_ext1 = zsb - 1; 1311 | dz_ext0 = dz0 - 3 * SQUISH_CONSTANT_4D; 1312 | dz_ext1 = dz0 + 1 - 2 * SQUISH_CONSTANT_4D; 1313 | } else { 1314 | zsv_ext0 = zsv_ext1 = zsb + 1; 1315 | dz_ext0 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D; 1316 | dz_ext1 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; 1317 | } 1318 | 1319 | if ((c1 & 0x08) == 0) { 1320 | wsv_ext0 = wsb; 1321 | wsv_ext1 = wsb - 1; 1322 | dw_ext0 = dw0 - 3 * SQUISH_CONSTANT_4D; 1323 | dw_ext1 = dw0 + 1 - 2 * SQUISH_CONSTANT_4D; 1324 | } else { 1325 | wsv_ext0 = wsv_ext1 = wsb + 1; 1326 | dw_ext0 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D; 1327 | dw_ext1 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; 1328 | } 1329 | 1330 | //One combination is a permutation of (0,0,0,2) based on c2 1331 | xsv_ext2 = xsb; 1332 | ysv_ext2 = ysb; 1333 | zsv_ext2 = zsb; 1334 | wsv_ext2 = wsb; 1335 | dx_ext2 = dx0 - 2 * SQUISH_CONSTANT_4D; 1336 | dy_ext2 = dy0 - 2 * SQUISH_CONSTANT_4D; 1337 | dz_ext2 = dz0 - 2 * SQUISH_CONSTANT_4D; 1338 | dw_ext2 = dw0 - 2 * SQUISH_CONSTANT_4D; 1339 | if ((c2 & 0x01) != 0) { 1340 | xsv_ext2 += 2; 1341 | dx_ext2 -= 2; 1342 | } else if ((c2 & 0x02) != 0) { 1343 | ysv_ext2 += 2; 1344 | dy_ext2 -= 2; 1345 | } else if ((c2 & 0x04) != 0) { 1346 | zsv_ext2 += 2; 1347 | dz_ext2 -= 2; 1348 | } else { 1349 | wsv_ext2 += 2; 1350 | dw_ext2 -= 2; 1351 | } 1352 | 1353 | } else { //Both closest points on the smaller side 1354 | //One of the two extra points is (0,0,0,0) 1355 | xsv_ext2 = xsb; 1356 | ysv_ext2 = ysb; 1357 | zsv_ext2 = zsb; 1358 | wsv_ext2 = wsb; 1359 | dx_ext2 = dx0; 1360 | dy_ext2 = dy0; 1361 | dz_ext2 = dz0; 1362 | dw_ext2 = dw0; 1363 | 1364 | //Other two points are based on the omitted axes. 1365 | byte c = (byte)(aPoint | bPoint); 1366 | 1367 | if ((c & 0x01) == 0) { 1368 | xsv_ext0 = xsb - 1; 1369 | xsv_ext1 = xsb; 1370 | dx_ext0 = dx0 + 1 - SQUISH_CONSTANT_4D; 1371 | dx_ext1 = dx0 - SQUISH_CONSTANT_4D; 1372 | } else { 1373 | xsv_ext0 = xsv_ext1 = xsb + 1; 1374 | dx_ext0 = dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_4D; 1375 | } 1376 | 1377 | if ((c & 0x02) == 0) { 1378 | ysv_ext0 = ysv_ext1 = ysb; 1379 | dy_ext0 = dy_ext1 = dy0 - SQUISH_CONSTANT_4D; 1380 | if ((c & 0x01) == 0x01) 1381 | { 1382 | ysv_ext0 -= 1; 1383 | dy_ext0 += 1; 1384 | } else { 1385 | ysv_ext1 -= 1; 1386 | dy_ext1 += 1; 1387 | } 1388 | } else { 1389 | ysv_ext0 = ysv_ext1 = ysb + 1; 1390 | dy_ext0 = dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_4D; 1391 | } 1392 | 1393 | if ((c & 0x04) == 0) { 1394 | zsv_ext0 = zsv_ext1 = zsb; 1395 | dz_ext0 = dz_ext1 = dz0 - SQUISH_CONSTANT_4D; 1396 | if ((c & 0x03) == 0x03) 1397 | { 1398 | zsv_ext0 -= 1; 1399 | dz_ext0 += 1; 1400 | } else { 1401 | zsv_ext1 -= 1; 1402 | dz_ext1 += 1; 1403 | } 1404 | } else { 1405 | zsv_ext0 = zsv_ext1 = zsb + 1; 1406 | dz_ext0 = dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_4D; 1407 | } 1408 | 1409 | if ((c & 0x08) == 0) 1410 | { 1411 | wsv_ext0 = wsb; 1412 | wsv_ext1 = wsb - 1; 1413 | dw_ext0 = dw0 - SQUISH_CONSTANT_4D; 1414 | dw_ext1 = dw0 + 1 - SQUISH_CONSTANT_4D; 1415 | } else { 1416 | wsv_ext0 = wsv_ext1 = wsb + 1; 1417 | dw_ext0 = dw_ext1 = dw0 - 1 - SQUISH_CONSTANT_4D; 1418 | } 1419 | 1420 | } 1421 | } else { //One point on each "side" 1422 | byte c1, c2; 1423 | if (aIsBiggerSide) { 1424 | c1 = aPoint; 1425 | c2 = bPoint; 1426 | } else { 1427 | c1 = bPoint; 1428 | c2 = aPoint; 1429 | } 1430 | 1431 | //Two contributions are the bigger-sided point with each 0 replaced with -1. 1432 | if ((c1 & 0x01) == 0) { 1433 | xsv_ext0 = xsb - 1; 1434 | xsv_ext1 = xsb; 1435 | dx_ext0 = dx0 + 1 - SQUISH_CONSTANT_4D; 1436 | dx_ext1 = dx0 - SQUISH_CONSTANT_4D; 1437 | } else { 1438 | xsv_ext0 = xsv_ext1 = xsb + 1; 1439 | dx_ext0 = dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_4D; 1440 | } 1441 | 1442 | if ((c1 & 0x02) == 0) { 1443 | ysv_ext0 = ysv_ext1 = ysb; 1444 | dy_ext0 = dy_ext1 = dy0 - SQUISH_CONSTANT_4D; 1445 | if ((c1 & 0x01) == 0x01) { 1446 | ysv_ext0 -= 1; 1447 | dy_ext0 += 1; 1448 | } else { 1449 | ysv_ext1 -= 1; 1450 | dy_ext1 += 1; 1451 | } 1452 | } else { 1453 | ysv_ext0 = ysv_ext1 = ysb + 1; 1454 | dy_ext0 = dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_4D; 1455 | } 1456 | 1457 | if ((c1 & 0x04) == 0) { 1458 | zsv_ext0 = zsv_ext1 = zsb; 1459 | dz_ext0 = dz_ext1 = dz0 - SQUISH_CONSTANT_4D; 1460 | if ((c1 & 0x03) == 0x03) { 1461 | zsv_ext0 -= 1; 1462 | dz_ext0 += 1; 1463 | } else { 1464 | zsv_ext1 -= 1; 1465 | dz_ext1 += 1; 1466 | } 1467 | } else { 1468 | zsv_ext0 = zsv_ext1 = zsb + 1; 1469 | dz_ext0 = dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_4D; 1470 | } 1471 | 1472 | if ((c1 & 0x08) == 0) { 1473 | wsv_ext0 = wsb; 1474 | wsv_ext1 = wsb - 1; 1475 | dw_ext0 = dw0 - SQUISH_CONSTANT_4D; 1476 | dw_ext1 = dw0 + 1 - SQUISH_CONSTANT_4D; 1477 | } else { 1478 | wsv_ext0 = wsv_ext1 = wsb + 1; 1479 | dw_ext0 = dw_ext1 = dw0 - 1 - SQUISH_CONSTANT_4D; 1480 | } 1481 | 1482 | //One contribution is a permutation of (0,0,0,2) based on the smaller-sided point 1483 | xsv_ext2 = xsb; 1484 | ysv_ext2 = ysb; 1485 | zsv_ext2 = zsb; 1486 | wsv_ext2 = wsb; 1487 | dx_ext2 = dx0 - 2 * SQUISH_CONSTANT_4D; 1488 | dy_ext2 = dy0 - 2 * SQUISH_CONSTANT_4D; 1489 | dz_ext2 = dz0 - 2 * SQUISH_CONSTANT_4D; 1490 | dw_ext2 = dw0 - 2 * SQUISH_CONSTANT_4D; 1491 | if ((c2 & 0x01) != 0) { 1492 | xsv_ext2 += 2; 1493 | dx_ext2 -= 2; 1494 | } else if ((c2 & 0x02) != 0) { 1495 | ysv_ext2 += 2; 1496 | dy_ext2 -= 2; 1497 | } else if ((c2 & 0x04) != 0) { 1498 | zsv_ext2 += 2; 1499 | dz_ext2 -= 2; 1500 | } else { 1501 | wsv_ext2 += 2; 1502 | dw_ext2 -= 2; 1503 | } 1504 | } 1505 | 1506 | //Contribution (1,0,0,0) 1507 | double dx1 = dx0 - 1 - SQUISH_CONSTANT_4D; 1508 | double dy1 = dy0 - 0 - SQUISH_CONSTANT_4D; 1509 | double dz1 = dz0 - 0 - SQUISH_CONSTANT_4D; 1510 | double dw1 = dw0 - 0 - SQUISH_CONSTANT_4D; 1511 | double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1 - dw1 * dw1; 1512 | if (attn1 > 0) { 1513 | attn1 *= attn1; 1514 | value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, zsb + 0, wsb + 0, dx1, dy1, dz1, dw1); 1515 | } 1516 | 1517 | //Contribution (0,1,0,0) 1518 | double dx2 = dx0 - 0 - SQUISH_CONSTANT_4D; 1519 | double dy2 = dy0 - 1 - SQUISH_CONSTANT_4D; 1520 | double dz2 = dz1; 1521 | double dw2 = dw1; 1522 | double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2 - dw2 * dw2; 1523 | if (attn2 > 0) { 1524 | attn2 *= attn2; 1525 | value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, zsb + 0, wsb + 0, dx2, dy2, dz2, dw2); 1526 | } 1527 | 1528 | //Contribution (0,0,1,0) 1529 | double dx3 = dx2; 1530 | double dy3 = dy1; 1531 | double dz3 = dz0 - 1 - SQUISH_CONSTANT_4D; 1532 | double dw3 = dw1; 1533 | double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3 - dw3 * dw3; 1534 | if (attn3 > 0) { 1535 | attn3 *= attn3; 1536 | value += attn3 * attn3 * extrapolate(xsb + 0, ysb + 0, zsb + 1, wsb + 0, dx3, dy3, dz3, dw3); 1537 | } 1538 | 1539 | //Contribution (0,0,0,1) 1540 | double dx4 = dx2; 1541 | double dy4 = dy1; 1542 | double dz4 = dz1; 1543 | double dw4 = dw0 - 1 - SQUISH_CONSTANT_4D; 1544 | double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4 - dw4 * dw4; 1545 | if (attn4 > 0) { 1546 | attn4 *= attn4; 1547 | value += attn4 * attn4 * extrapolate(xsb + 0, ysb + 0, zsb + 0, wsb + 1, dx4, dy4, dz4, dw4); 1548 | } 1549 | 1550 | //Contribution (1,1,0,0) 1551 | double dx5 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; 1552 | double dy5 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; 1553 | double dz5 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D; 1554 | double dw5 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D; 1555 | double attn5 = 2 - dx5 * dx5 - dy5 * dy5 - dz5 * dz5 - dw5 * dw5; 1556 | if (attn5 > 0) { 1557 | attn5 *= attn5; 1558 | value += attn5 * attn5 * extrapolate(xsb + 1, ysb + 1, zsb + 0, wsb + 0, dx5, dy5, dz5, dw5); 1559 | } 1560 | 1561 | //Contribution (1,0,1,0) 1562 | double dx6 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; 1563 | double dy6 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D; 1564 | double dz6 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; 1565 | double dw6 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D; 1566 | double attn6 = 2 - dx6 * dx6 - dy6 * dy6 - dz6 * dz6 - dw6 * dw6; 1567 | if (attn6 > 0) { 1568 | attn6 *= attn6; 1569 | value += attn6 * attn6 * extrapolate(xsb + 1, ysb + 0, zsb + 1, wsb + 0, dx6, dy6, dz6, dw6); 1570 | } 1571 | 1572 | //Contribution (1,0,0,1) 1573 | double dx7 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; 1574 | double dy7 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D; 1575 | double dz7 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D; 1576 | double dw7 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; 1577 | double attn7 = 2 - dx7 * dx7 - dy7 * dy7 - dz7 * dz7 - dw7 * dw7; 1578 | if (attn7 > 0) { 1579 | attn7 *= attn7; 1580 | value += attn7 * attn7 * extrapolate(xsb + 1, ysb + 0, zsb + 0, wsb + 1, dx7, dy7, dz7, dw7); 1581 | } 1582 | 1583 | //Contribution (0,1,1,0) 1584 | double dx8 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D; 1585 | double dy8 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; 1586 | double dz8 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; 1587 | double dw8 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D; 1588 | double attn8 = 2 - dx8 * dx8 - dy8 * dy8 - dz8 * dz8 - dw8 * dw8; 1589 | if (attn8 > 0) { 1590 | attn8 *= attn8; 1591 | value += attn8 * attn8 * extrapolate(xsb + 0, ysb + 1, zsb + 1, wsb + 0, dx8, dy8, dz8, dw8); 1592 | } 1593 | 1594 | //Contribution (0,1,0,1) 1595 | double dx9 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D; 1596 | double dy9 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; 1597 | double dz9 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D; 1598 | double dw9 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; 1599 | double attn9 = 2 - dx9 * dx9 - dy9 * dy9 - dz9 * dz9 - dw9 * dw9; 1600 | if (attn9 > 0) { 1601 | attn9 *= attn9; 1602 | value += attn9 * attn9 * extrapolate(xsb + 0, ysb + 1, zsb + 0, wsb + 1, dx9, dy9, dz9, dw9); 1603 | } 1604 | 1605 | //Contribution (0,0,1,1) 1606 | double dx10 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D; 1607 | double dy10 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D; 1608 | double dz10 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; 1609 | double dw10 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; 1610 | double attn10 = 2 - dx10 * dx10 - dy10 * dy10 - dz10 * dz10 - dw10 * dw10; 1611 | if (attn10 > 0) { 1612 | attn10 *= attn10; 1613 | value += attn10 * attn10 * extrapolate(xsb + 0, ysb + 0, zsb + 1, wsb + 1, dx10, dy10, dz10, dw10); 1614 | } 1615 | } else { //We're inside the second dispentachoron (Rectified 4-Simplex) 1616 | double aScore; 1617 | byte aPoint; 1618 | boolean aIsBiggerSide = true; 1619 | double bScore; 1620 | byte bPoint; 1621 | boolean bIsBiggerSide = true; 1622 | 1623 | //Decide between (0,0,1,1) and (1,1,0,0) 1624 | if (xins + yins < zins + wins) { 1625 | aScore = xins + yins; 1626 | aPoint = 0x0C; 1627 | } else { 1628 | aScore = zins + wins; 1629 | aPoint = 0x03; 1630 | } 1631 | 1632 | //Decide between (0,1,0,1) and (1,0,1,0) 1633 | if (xins + zins < yins + wins) { 1634 | bScore = xins + zins; 1635 | bPoint = 0x0A; 1636 | } else { 1637 | bScore = yins + wins; 1638 | bPoint = 0x05; 1639 | } 1640 | 1641 | //Closer between (0,1,1,0) and (1,0,0,1) will replace the further of a and b, if closer. 1642 | if (xins + wins < yins + zins) { 1643 | double score = xins + wins; 1644 | if (aScore <= bScore && score < bScore) { 1645 | bScore = score; 1646 | bPoint = 0x06; 1647 | } else if (aScore > bScore && score < aScore) { 1648 | aScore = score; 1649 | aPoint = 0x06; 1650 | } 1651 | } else { 1652 | double score = yins + zins; 1653 | if (aScore <= bScore && score < bScore) { 1654 | bScore = score; 1655 | bPoint = 0x09; 1656 | } else if (aScore > bScore && score < aScore) { 1657 | aScore = score; 1658 | aPoint = 0x09; 1659 | } 1660 | } 1661 | 1662 | //Decide if (0,1,1,1) is closer. 1663 | double p1 = 3 - inSum + xins; 1664 | if (aScore <= bScore && p1 < bScore) { 1665 | bScore = p1; 1666 | bPoint = 0x0E; 1667 | bIsBiggerSide = false; 1668 | } else if (aScore > bScore && p1 < aScore) { 1669 | aScore = p1; 1670 | aPoint = 0x0E; 1671 | aIsBiggerSide = false; 1672 | } 1673 | 1674 | //Decide if (1,0,1,1) is closer. 1675 | double p2 = 3 - inSum + yins; 1676 | if (aScore <= bScore && p2 < bScore) { 1677 | bScore = p2; 1678 | bPoint = 0x0D; 1679 | bIsBiggerSide = false; 1680 | } else if (aScore > bScore && p2 < aScore) { 1681 | aScore = p2; 1682 | aPoint = 0x0D; 1683 | aIsBiggerSide = false; 1684 | } 1685 | 1686 | //Decide if (1,1,0,1) is closer. 1687 | double p3 = 3 - inSum + zins; 1688 | if (aScore <= bScore && p3 < bScore) { 1689 | bScore = p3; 1690 | bPoint = 0x0B; 1691 | bIsBiggerSide = false; 1692 | } else if (aScore > bScore && p3 < aScore) { 1693 | aScore = p3; 1694 | aPoint = 0x0B; 1695 | aIsBiggerSide = false; 1696 | } 1697 | 1698 | //Decide if (1,1,1,0) is closer. 1699 | double p4 = 3 - inSum + wins; 1700 | if (aScore <= bScore && p4 < bScore) { 1701 | bScore = p4; 1702 | bPoint = 0x07; 1703 | bIsBiggerSide = false; 1704 | } else if (aScore > bScore && p4 < aScore) { 1705 | aScore = p4; 1706 | aPoint = 0x07; 1707 | aIsBiggerSide = false; 1708 | } 1709 | 1710 | //Where each of the two closest points are determines how the extra three vertices are calculated. 1711 | if (aIsBiggerSide == bIsBiggerSide) { 1712 | if (aIsBiggerSide) { //Both closest points on the bigger side 1713 | byte c1 = (byte)(aPoint & bPoint); 1714 | byte c2 = (byte)(aPoint | bPoint); 1715 | 1716 | //Two contributions are permutations of (0,0,0,1) and (0,0,0,2) based on c1 1717 | xsv_ext0 = xsv_ext1 = xsb; 1718 | ysv_ext0 = ysv_ext1 = ysb; 1719 | zsv_ext0 = zsv_ext1 = zsb; 1720 | wsv_ext0 = wsv_ext1 = wsb; 1721 | dx_ext0 = dx0 - SQUISH_CONSTANT_4D; 1722 | dy_ext0 = dy0 - SQUISH_CONSTANT_4D; 1723 | dz_ext0 = dz0 - SQUISH_CONSTANT_4D; 1724 | dw_ext0 = dw0 - SQUISH_CONSTANT_4D; 1725 | dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_4D; 1726 | dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_4D; 1727 | dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_4D; 1728 | dw_ext1 = dw0 - 2 * SQUISH_CONSTANT_4D; 1729 | if ((c1 & 0x01) != 0) { 1730 | xsv_ext0 += 1; 1731 | dx_ext0 -= 1; 1732 | xsv_ext1 += 2; 1733 | dx_ext1 -= 2; 1734 | } else if ((c1 & 0x02) != 0) { 1735 | ysv_ext0 += 1; 1736 | dy_ext0 -= 1; 1737 | ysv_ext1 += 2; 1738 | dy_ext1 -= 2; 1739 | } else if ((c1 & 0x04) != 0) { 1740 | zsv_ext0 += 1; 1741 | dz_ext0 -= 1; 1742 | zsv_ext1 += 2; 1743 | dz_ext1 -= 2; 1744 | } else { 1745 | wsv_ext0 += 1; 1746 | dw_ext0 -= 1; 1747 | wsv_ext1 += 2; 1748 | dw_ext1 -= 2; 1749 | } 1750 | 1751 | //One contribution is a permutation of (1,1,1,-1) based on c2 1752 | xsv_ext2 = xsb + 1; 1753 | ysv_ext2 = ysb + 1; 1754 | zsv_ext2 = zsb + 1; 1755 | wsv_ext2 = wsb + 1; 1756 | dx_ext2 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; 1757 | dy_ext2 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; 1758 | dz_ext2 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; 1759 | dw_ext2 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; 1760 | if ((c2 & 0x01) == 0) { 1761 | xsv_ext2 -= 2; 1762 | dx_ext2 += 2; 1763 | } else if ((c2 & 0x02) == 0) { 1764 | ysv_ext2 -= 2; 1765 | dy_ext2 += 2; 1766 | } else if ((c2 & 0x04) == 0) { 1767 | zsv_ext2 -= 2; 1768 | dz_ext2 += 2; 1769 | } else { 1770 | wsv_ext2 -= 2; 1771 | dw_ext2 += 2; 1772 | } 1773 | } else { //Both closest points on the smaller side 1774 | //One of the two extra points is (1,1,1,1) 1775 | xsv_ext2 = xsb + 1; 1776 | ysv_ext2 = ysb + 1; 1777 | zsv_ext2 = zsb + 1; 1778 | wsv_ext2 = wsb + 1; 1779 | dx_ext2 = dx0 - 1 - 4 * SQUISH_CONSTANT_4D; 1780 | dy_ext2 = dy0 - 1 - 4 * SQUISH_CONSTANT_4D; 1781 | dz_ext2 = dz0 - 1 - 4 * SQUISH_CONSTANT_4D; 1782 | dw_ext2 = dw0 - 1 - 4 * SQUISH_CONSTANT_4D; 1783 | 1784 | //Other two points are based on the shared axes. 1785 | byte c = (byte)(aPoint & bPoint); 1786 | 1787 | if ((c & 0x01) != 0) { 1788 | xsv_ext0 = xsb + 2; 1789 | xsv_ext1 = xsb + 1; 1790 | dx_ext0 = dx0 - 2 - 3 * SQUISH_CONSTANT_4D; 1791 | dx_ext1 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D; 1792 | } else { 1793 | xsv_ext0 = xsv_ext1 = xsb; 1794 | dx_ext0 = dx_ext1 = dx0 - 3 * SQUISH_CONSTANT_4D; 1795 | } 1796 | 1797 | if ((c & 0x02) != 0) { 1798 | ysv_ext0 = ysv_ext1 = ysb + 1; 1799 | dy_ext0 = dy_ext1 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D; 1800 | if ((c & 0x01) == 0) 1801 | { 1802 | ysv_ext0 += 1; 1803 | dy_ext0 -= 1; 1804 | } else { 1805 | ysv_ext1 += 1; 1806 | dy_ext1 -= 1; 1807 | } 1808 | } else { 1809 | ysv_ext0 = ysv_ext1 = ysb; 1810 | dy_ext0 = dy_ext1 = dy0 - 3 * SQUISH_CONSTANT_4D; 1811 | } 1812 | 1813 | if ((c & 0x04) != 0) { 1814 | zsv_ext0 = zsv_ext1 = zsb + 1; 1815 | dz_ext0 = dz_ext1 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D; 1816 | if ((c & 0x03) == 0) 1817 | { 1818 | zsv_ext0 += 1; 1819 | dz_ext0 -= 1; 1820 | } else { 1821 | zsv_ext1 += 1; 1822 | dz_ext1 -= 1; 1823 | } 1824 | } else { 1825 | zsv_ext0 = zsv_ext1 = zsb; 1826 | dz_ext0 = dz_ext1 = dz0 - 3 * SQUISH_CONSTANT_4D; 1827 | } 1828 | 1829 | if ((c & 0x08) != 0) 1830 | { 1831 | wsv_ext0 = wsb + 1; 1832 | wsv_ext1 = wsb + 2; 1833 | dw_ext0 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D; 1834 | dw_ext1 = dw0 - 2 - 3 * SQUISH_CONSTANT_4D; 1835 | } else { 1836 | wsv_ext0 = wsv_ext1 = wsb; 1837 | dw_ext0 = dw_ext1 = dw0 - 3 * SQUISH_CONSTANT_4D; 1838 | } 1839 | } 1840 | } else { //One point on each "side" 1841 | byte c1, c2; 1842 | if (aIsBiggerSide) { 1843 | c1 = aPoint; 1844 | c2 = bPoint; 1845 | } else { 1846 | c1 = bPoint; 1847 | c2 = aPoint; 1848 | } 1849 | 1850 | //Two contributions are the bigger-sided point with each 1 replaced with 2. 1851 | if ((c1 & 0x01) != 0) { 1852 | xsv_ext0 = xsb + 2; 1853 | xsv_ext1 = xsb + 1; 1854 | dx_ext0 = dx0 - 2 - 3 * SQUISH_CONSTANT_4D; 1855 | dx_ext1 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D; 1856 | } else { 1857 | xsv_ext0 = xsv_ext1 = xsb; 1858 | dx_ext0 = dx_ext1 = dx0 - 3 * SQUISH_CONSTANT_4D; 1859 | } 1860 | 1861 | if ((c1 & 0x02) != 0) { 1862 | ysv_ext0 = ysv_ext1 = ysb + 1; 1863 | dy_ext0 = dy_ext1 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D; 1864 | if ((c1 & 0x01) == 0) { 1865 | ysv_ext0 += 1; 1866 | dy_ext0 -= 1; 1867 | } else { 1868 | ysv_ext1 += 1; 1869 | dy_ext1 -= 1; 1870 | } 1871 | } else { 1872 | ysv_ext0 = ysv_ext1 = ysb; 1873 | dy_ext0 = dy_ext1 = dy0 - 3 * SQUISH_CONSTANT_4D; 1874 | } 1875 | 1876 | if ((c1 & 0x04) != 0) { 1877 | zsv_ext0 = zsv_ext1 = zsb + 1; 1878 | dz_ext0 = dz_ext1 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D; 1879 | if ((c1 & 0x03) == 0) { 1880 | zsv_ext0 += 1; 1881 | dz_ext0 -= 1; 1882 | } else { 1883 | zsv_ext1 += 1; 1884 | dz_ext1 -= 1; 1885 | } 1886 | } else { 1887 | zsv_ext0 = zsv_ext1 = zsb; 1888 | dz_ext0 = dz_ext1 = dz0 - 3 * SQUISH_CONSTANT_4D; 1889 | } 1890 | 1891 | if ((c1 & 0x08) != 0) { 1892 | wsv_ext0 = wsb + 1; 1893 | wsv_ext1 = wsb + 2; 1894 | dw_ext0 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D; 1895 | dw_ext1 = dw0 - 2 - 3 * SQUISH_CONSTANT_4D; 1896 | } else { 1897 | wsv_ext0 = wsv_ext1 = wsb; 1898 | dw_ext0 = dw_ext1 = dw0 - 3 * SQUISH_CONSTANT_4D; 1899 | } 1900 | 1901 | //One contribution is a permutation of (1,1,1,-1) based on the smaller-sided point 1902 | xsv_ext2 = xsb + 1; 1903 | ysv_ext2 = ysb + 1; 1904 | zsv_ext2 = zsb + 1; 1905 | wsv_ext2 = wsb + 1; 1906 | dx_ext2 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; 1907 | dy_ext2 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; 1908 | dz_ext2 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; 1909 | dw_ext2 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; 1910 | if ((c2 & 0x01) == 0) { 1911 | xsv_ext2 -= 2; 1912 | dx_ext2 += 2; 1913 | } else if ((c2 & 0x02) == 0) { 1914 | ysv_ext2 -= 2; 1915 | dy_ext2 += 2; 1916 | } else if ((c2 & 0x04) == 0) { 1917 | zsv_ext2 -= 2; 1918 | dz_ext2 += 2; 1919 | } else { 1920 | wsv_ext2 -= 2; 1921 | dw_ext2 += 2; 1922 | } 1923 | } 1924 | 1925 | //Contribution (1,1,1,0) 1926 | double dx4 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D; 1927 | double dy4 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D; 1928 | double dz4 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D; 1929 | double dw4 = dw0 - 3 * SQUISH_CONSTANT_4D; 1930 | double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4 - dw4 * dw4; 1931 | if (attn4 > 0) { 1932 | attn4 *= attn4; 1933 | value += attn4 * attn4 * extrapolate(xsb + 1, ysb + 1, zsb + 1, wsb + 0, dx4, dy4, dz4, dw4); 1934 | } 1935 | 1936 | //Contribution (1,1,0,1) 1937 | double dx3 = dx4; 1938 | double dy3 = dy4; 1939 | double dz3 = dz0 - 3 * SQUISH_CONSTANT_4D; 1940 | double dw3 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D; 1941 | double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3 - dw3 * dw3; 1942 | if (attn3 > 0) { 1943 | attn3 *= attn3; 1944 | value += attn3 * attn3 * extrapolate(xsb + 1, ysb + 1, zsb + 0, wsb + 1, dx3, dy3, dz3, dw3); 1945 | } 1946 | 1947 | //Contribution (1,0,1,1) 1948 | double dx2 = dx4; 1949 | double dy2 = dy0 - 3 * SQUISH_CONSTANT_4D; 1950 | double dz2 = dz4; 1951 | double dw2 = dw3; 1952 | double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2 - dw2 * dw2; 1953 | if (attn2 > 0) { 1954 | attn2 *= attn2; 1955 | value += attn2 * attn2 * extrapolate(xsb + 1, ysb + 0, zsb + 1, wsb + 1, dx2, dy2, dz2, dw2); 1956 | } 1957 | 1958 | //Contribution (0,1,1,1) 1959 | double dx1 = dx0 - 3 * SQUISH_CONSTANT_4D; 1960 | double dz1 = dz4; 1961 | double dy1 = dy4; 1962 | double dw1 = dw3; 1963 | double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1 - dw1 * dw1; 1964 | if (attn1 > 0) { 1965 | attn1 *= attn1; 1966 | value += attn1 * attn1 * extrapolate(xsb + 0, ysb + 1, zsb + 1, wsb + 1, dx1, dy1, dz1, dw1); 1967 | } 1968 | 1969 | //Contribution (1,1,0,0) 1970 | double dx5 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; 1971 | double dy5 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; 1972 | double dz5 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D; 1973 | double dw5 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D; 1974 | double attn5 = 2 - dx5 * dx5 - dy5 * dy5 - dz5 * dz5 - dw5 * dw5; 1975 | if (attn5 > 0) { 1976 | attn5 *= attn5; 1977 | value += attn5 * attn5 * extrapolate(xsb + 1, ysb + 1, zsb + 0, wsb + 0, dx5, dy5, dz5, dw5); 1978 | } 1979 | 1980 | //Contribution (1,0,1,0) 1981 | double dx6 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; 1982 | double dy6 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D; 1983 | double dz6 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; 1984 | double dw6 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D; 1985 | double attn6 = 2 - dx6 * dx6 - dy6 * dy6 - dz6 * dz6 - dw6 * dw6; 1986 | if (attn6 > 0) { 1987 | attn6 *= attn6; 1988 | value += attn6 * attn6 * extrapolate(xsb + 1, ysb + 0, zsb + 1, wsb + 0, dx6, dy6, dz6, dw6); 1989 | } 1990 | 1991 | //Contribution (1,0,0,1) 1992 | double dx7 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D; 1993 | double dy7 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D; 1994 | double dz7 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D; 1995 | double dw7 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; 1996 | double attn7 = 2 - dx7 * dx7 - dy7 * dy7 - dz7 * dz7 - dw7 * dw7; 1997 | if (attn7 > 0) { 1998 | attn7 *= attn7; 1999 | value += attn7 * attn7 * extrapolate(xsb + 1, ysb + 0, zsb + 0, wsb + 1, dx7, dy7, dz7, dw7); 2000 | } 2001 | 2002 | //Contribution (0,1,1,0) 2003 | double dx8 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D; 2004 | double dy8 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; 2005 | double dz8 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; 2006 | double dw8 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D; 2007 | double attn8 = 2 - dx8 * dx8 - dy8 * dy8 - dz8 * dz8 - dw8 * dw8; 2008 | if (attn8 > 0) { 2009 | attn8 *= attn8; 2010 | value += attn8 * attn8 * extrapolate(xsb + 0, ysb + 1, zsb + 1, wsb + 0, dx8, dy8, dz8, dw8); 2011 | } 2012 | 2013 | //Contribution (0,1,0,1) 2014 | double dx9 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D; 2015 | double dy9 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D; 2016 | double dz9 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D; 2017 | double dw9 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; 2018 | double attn9 = 2 - dx9 * dx9 - dy9 * dy9 - dz9 * dz9 - dw9 * dw9; 2019 | if (attn9 > 0) { 2020 | attn9 *= attn9; 2021 | value += attn9 * attn9 * extrapolate(xsb + 0, ysb + 1, zsb + 0, wsb + 1, dx9, dy9, dz9, dw9); 2022 | } 2023 | 2024 | //Contribution (0,0,1,1) 2025 | double dx10 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D; 2026 | double dy10 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D; 2027 | double dz10 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D; 2028 | double dw10 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D; 2029 | double attn10 = 2 - dx10 * dx10 - dy10 * dy10 - dz10 * dz10 - dw10 * dw10; 2030 | if (attn10 > 0) { 2031 | attn10 *= attn10; 2032 | value += attn10 * attn10 * extrapolate(xsb + 0, ysb + 0, zsb + 1, wsb + 1, dx10, dy10, dz10, dw10); 2033 | } 2034 | } 2035 | 2036 | //First extra vertex 2037 | double attn_ext0 = 2 - dx_ext0 * dx_ext0 - dy_ext0 * dy_ext0 - dz_ext0 * dz_ext0 - dw_ext0 * dw_ext0; 2038 | if (attn_ext0 > 0) 2039 | { 2040 | attn_ext0 *= attn_ext0; 2041 | value += attn_ext0 * attn_ext0 * extrapolate(xsv_ext0, ysv_ext0, zsv_ext0, wsv_ext0, dx_ext0, dy_ext0, dz_ext0, dw_ext0); 2042 | } 2043 | 2044 | //Second extra vertex 2045 | double attn_ext1 = 2 - dx_ext1 * dx_ext1 - dy_ext1 * dy_ext1 - dz_ext1 * dz_ext1 - dw_ext1 * dw_ext1; 2046 | if (attn_ext1 > 0) 2047 | { 2048 | attn_ext1 *= attn_ext1; 2049 | value += attn_ext1 * attn_ext1 * extrapolate(xsv_ext1, ysv_ext1, zsv_ext1, wsv_ext1, dx_ext1, dy_ext1, dz_ext1, dw_ext1); 2050 | } 2051 | 2052 | //Third extra vertex 2053 | double attn_ext2 = 2 - dx_ext2 * dx_ext2 - dy_ext2 * dy_ext2 - dz_ext2 * dz_ext2 - dw_ext2 * dw_ext2; 2054 | if (attn_ext2 > 0) 2055 | { 2056 | attn_ext2 *= attn_ext2; 2057 | value += attn_ext2 * attn_ext2 * extrapolate(xsv_ext2, ysv_ext2, zsv_ext2, wsv_ext2, dx_ext2, dy_ext2, dz_ext2, dw_ext2); 2058 | } 2059 | 2060 | return value / NORM_CONSTANT_4D; 2061 | } 2062 | 2063 | private double extrapolate(int xsb, int ysb, double dx, double dy) 2064 | { 2065 | int index = perm[(perm[xsb & 0xFF] + ysb) & 0xFF] & 0x0E; 2066 | return gradients2D[index] * dx 2067 | + gradients2D[index + 1] * dy; 2068 | } 2069 | 2070 | private double extrapolate(int xsb, int ysb, int zsb, double dx, double dy, double dz) 2071 | { 2072 | int index = permGradIndex3D[(perm[(perm[xsb & 0xFF] + ysb) & 0xFF] + zsb) & 0xFF]; 2073 | return gradients3D[index] * dx 2074 | + gradients3D[index + 1] * dy 2075 | + gradients3D[index + 2] * dz; 2076 | } 2077 | 2078 | private double extrapolate(int xsb, int ysb, int zsb, int wsb, double dx, double dy, double dz, double dw) 2079 | { 2080 | int index = perm[(perm[(perm[(perm[xsb & 0xFF] + ysb) & 0xFF] + zsb) & 0xFF] + wsb) & 0xFF] & 0xFC; 2081 | return gradients4D[index] * dx 2082 | + gradients4D[index + 1] * dy 2083 | + gradients4D[index + 2] * dz 2084 | + gradients4D[index + 3] * dw; 2085 | } 2086 | 2087 | private static int fastFloor(double x) { 2088 | int xi = (int)x; 2089 | return x < xi ? xi - 1 : xi; 2090 | } 2091 | 2092 | //Gradients for 2D. They approximate the directions to the 2093 | //vertices of an octagon from the center. 2094 | private static byte[] gradients2D = new byte[] { 2095 | 5, 2, 2, 5, 2096 | -5, 2, -2, 5, 2097 | 5, -2, 2, -5, 2098 | -5, -2, -2, -5, 2099 | }; 2100 | 2101 | //Gradients for 3D. They approximate the directions to the 2102 | //vertices of a rhombicuboctahedron from the center, skewed so 2103 | //that the triangular and square facets can be inscribed inside 2104 | //circles of the same radius. 2105 | private static byte[] gradients3D = new byte[] { 2106 | -11, 4, 4, -4, 11, 4, -4, 4, 11, 2107 | 11, 4, 4, 4, 11, 4, 4, 4, 11, 2108 | -11, -4, 4, -4, -11, 4, -4, -4, 11, 2109 | 11, -4, 4, 4, -11, 4, 4, -4, 11, 2110 | -11, 4, -4, -4, 11, -4, -4, 4, -11, 2111 | 11, 4, -4, 4, 11, -4, 4, 4, -11, 2112 | -11, -4, -4, -4, -11, -4, -4, -4, -11, 2113 | 11, -4, -4, 4, -11, -4, 4, -4, -11, 2114 | }; 2115 | 2116 | //Gradients for 4D. They approximate the directions to the 2117 | //vertices of a disprismatotesseractihexadecachoron from the center, 2118 | //skewed so that the tetrahedral and cubic facets can be inscribed inside 2119 | //spheres of the same radius. 2120 | private static byte[] gradients4D = new byte[] { 2121 | 3, 1, 1, 1, 1, 3, 1, 1, 1, 1, 3, 1, 1, 1, 1, 3, 2122 | -3, 1, 1, 1, -1, 3, 1, 1, -1, 1, 3, 1, -1, 1, 1, 3, 2123 | 3, -1, 1, 1, 1, -3, 1, 1, 1, -1, 3, 1, 1, -1, 1, 3, 2124 | -3, -1, 1, 1, -1, -3, 1, 1, -1, -1, 3, 1, -1, -1, 1, 3, 2125 | 3, 1, -1, 1, 1, 3, -1, 1, 1, 1, -3, 1, 1, 1, -1, 3, 2126 | -3, 1, -1, 1, -1, 3, -1, 1, -1, 1, -3, 1, -1, 1, -1, 3, 2127 | 3, -1, -1, 1, 1, -3, -1, 1, 1, -1, -3, 1, 1, -1, -1, 3, 2128 | -3, -1, -1, 1, -1, -3, -1, 1, -1, -1, -3, 1, -1, -1, -1, 3, 2129 | 3, 1, 1, -1, 1, 3, 1, -1, 1, 1, 3, -1, 1, 1, 1, -3, 2130 | -3, 1, 1, -1, -1, 3, 1, -1, -1, 1, 3, -1, -1, 1, 1, -3, 2131 | 3, -1, 1, -1, 1, -3, 1, -1, 1, -1, 3, -1, 1, -1, 1, -3, 2132 | -3, -1, 1, -1, -1, -3, 1, -1, -1, -1, 3, -1, -1, -1, 1, -3, 2133 | 3, 1, -1, -1, 1, 3, -1, -1, 1, 1, -3, -1, 1, 1, -1, -3, 2134 | -3, 1, -1, -1, -1, 3, -1, -1, -1, 1, -3, -1, -1, 1, -1, -3, 2135 | 3, -1, -1, -1, 1, -3, -1, -1, 1, -1, -3, -1, 1, -1, -1, -3, 2136 | -3, -1, -1, -1, -1, -3, -1, -1, -1, -1, -3, -1, -1, -1, -1, -3, 2137 | }; 2138 | } 2139 | --------------------------------------------------------------------------------