diff --git a/forge-adventure/pom.xml b/forge-adventure/pom.xml
index 3eceabd51e7..3e43a04af9a 100644
--- a/forge-adventure/pom.xml
+++ b/forge-adventure/pom.xml
@@ -10,6 +10,48 @@
4.0.0
forge-adventure
+ jar
+ Forge Adventure
+
+
+ src
+
+
+ maven-compiler-plugin
+
+ 1.8
+ 1.8
+
+
+
+
+ maven-assembly-plugin
+
+ false
+
+ jar-with-dependencies
+
+
+
+ forge.adventure.Main
+ true
+
+
+
+
+
+ make-assembly
+
+ package
+
+
+ single
+
+
+
+
+
+
com.badlogicgames.gdx
@@ -39,6 +81,12 @@
1.10.0
compile
+
+ com.badlogicgames.gdx
+ gdx-freetype-platform
+ 1.10.0
+ natives-desktop
+
forge
forge-gui
diff --git a/forge-adventure/sentry.properties b/forge-adventure/sentry.properties
new file mode 100644
index 00000000000..683ff25e08a
--- /dev/null
+++ b/forge-adventure/sentry.properties
@@ -0,0 +1,14 @@
+# ideally this should be using HTTPS, but this is fine for now
+dsn=http://a0b8dbad9b8a49cfa51bf65d462e8dae@sentry.cardforge.org:9000/2
+stacktrace.app.packages=forge
+
+# where to store events if offline or can't reach the above server
+buffer.dir=sentry-events
+buffer.size=100
+
+# allow ample time for graceful shutdown
+buffer.shutdowntimeout=5000
+async.shutdowntimeout=5000
+
+# allow longer messages
+maxmessagelength=1500
\ No newline at end of file
diff --git a/forge-adventure/src/main/java/forge/adventure/AdventureApplicationAdapter.java b/forge-adventure/src/main/java/forge/adventure/AdventureApplicationAdapter.java
index 69387c1ae0a..ca4bc1fb33a 100644
--- a/forge-adventure/src/main/java/forge/adventure/AdventureApplicationAdapter.java
+++ b/forge-adventure/src/main/java/forge/adventure/AdventureApplicationAdapter.java
@@ -1,36 +1,55 @@
package forge.adventure;
import com.badlogic.gdx.ApplicationAdapter;
-import forge.adventure.scene.*;
+import forge.Graphics;
+import forge.adventure.scene.Scene;
+import forge.adventure.scene.SceneType;
import forge.adventure.util.Res;
-import java.util.HashMap;
-
public class AdventureApplicationAdapter extends ApplicationAdapter {
public static AdventureApplicationAdapter CurrentAdapter;
String strPlane;
Scene currentScene=null;
- HashMap allScenes= new HashMap<>();
+ Scene lastScene=null;
Res resourcesLoader;
+ private int currentWidth;
+ private int currentHeight;
+ private Graphics graphics;
+
+ public int getCurrentWidth(){return currentWidth;}
+ public int getCurrentHeight(){return currentHeight;}
+ public Graphics getGraphics(){return graphics;}
+ @Override
+ public void resize(int w,int h)
+ {
+ currentWidth=w;
+ currentHeight=h;
+ super.resize(w,h);
+ }
public AdventureApplicationAdapter(String plane) {
CurrentAdapter=this;
strPlane=plane;
- allScenes.put(SceneType.StartScene,new StartScene());
- allScenes.put(SceneType.NewGameScene,new NewGameScene());
- allScenes.put(SceneType.GameScene,new GameScene());
- allScenes.put(SceneType.DuelScene,new DuelScene());
}
- public boolean SwitchScene(SceneType newScene)
+ public boolean SwitchScene(Scene newScene)
{
if(currentScene!=null)
{
if(!currentScene.Leave())
return false;
}
- currentScene=allScenes.get(newScene);
+ lastScene=currentScene;
+ currentScene=newScene;
currentScene.Enter();
return true;
}
+ public void ResLoaded()
+ {
+ for( forge.adventure.scene.SceneType entry:SceneType.values())
+ {
+ entry.instance.ResLoaded();
+ }
+
+ }
public Res GetRes()
{
return resourcesLoader;
@@ -38,12 +57,13 @@ public class AdventureApplicationAdapter extends ApplicationAdapter {
@Override
public void create ()
{
+ graphics = new Graphics();
resourcesLoader=new Res(strPlane);
- for(HashMap.Entry entry:allScenes.entrySet())
+ for( forge.adventure.scene.SceneType entry:SceneType.values())
{
- entry.getValue().create();
+ entry.instance.create();
}
- SwitchScene(SceneType.StartScene);
+ SwitchScene(SceneType.StartScene.instance);
}
@Override
public void render(){
@@ -53,4 +73,8 @@ public class AdventureApplicationAdapter extends ApplicationAdapter {
public void dispose(){
currentScene.dispose();
}
+
+ public Scene GetLastScene() {
+ return lastScene;
+ }
}
diff --git a/forge-adventure/src/main/java/forge/adventure/Main.java b/forge-adventure/src/main/java/forge/adventure/Main.java
index 29d5a553b2f..22485f5ef07 100644
--- a/forge-adventure/src/main/java/forge/adventure/Main.java
+++ b/forge-adventure/src/main/java/forge/adventure/Main.java
@@ -1,15 +1,15 @@
package forge.adventure;
-import com.badlogic.gdx.Application;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application;
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Clipboard;
+import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.utils.Clipboard;
import forge.Forge;
import forge.FrameRate;
-import forge.Graphics;
import forge.GuiMobile;
+import forge.adventure.scene.SettingsScene;
import forge.assets.AssetsDownloader;
import forge.assets.FSkin;
import forge.assets.FSkinFont;
@@ -39,9 +39,6 @@ class StartAdvanture extends AdventureApplicationAdapter
{
private static Clipboard clipboard;
private static IDeviceAdapter deviceAdapter;
- private static int screenWidth;
- private static int screenHeight;
- private static Graphics graphics;
private static FrameRate frameRate;
private static FScreen currentScreen;
private static SplashScreen splashScreen;
@@ -75,22 +72,62 @@ class StartAdvanture extends AdventureApplicationAdapter
public StartAdvanture(String plane) {
super(plane);
+
+ Forge.isTabletDevice=true;
+ Forge.isPortraitMode=false;
+ Forge.hdbuttons = true;
+ Forge.hdstart = true;
+ Forge app= (Forge) Forge.getApp(new Lwjgl3Clipboard(),null,"../forge-gui/",true,false,0,true,0,"","");
+
+ app.resize(1920,1080);
clipboard = new Lwjgl3Clipboard();
GuiBase.setUsingAppDirectory(false); //obb directory on android uses the package name as entrypoint
GuiBase.setInterface(new GuiMobile("../forge-gui/"));
GuiBase.enablePropertyConfig(true);
isPortraitMode = true;
totalDeviceRAM = 0;
+
+
+ GuiBase.setDeviceInfo("", "", 0, 0);
+
+
+ }
+ @Override
+ public void render()
+ {
+ if(splashScreen!=null)
+ {
+ Gdx.gl.glClearColor(1,0,1,1);
+ Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); // Clear the screen.
+ getGraphics().begin(getCurrentWidth(), getCurrentHeight());
+ splashScreen.setSize(getCurrentWidth(), getCurrentHeight());
+ splashScreen.screenPos.setSize(getCurrentWidth(), getCurrentHeight());
+ if (splashScreen.getRotate180()) {
+ getGraphics().startRotateTransform(getCurrentWidth() / 2, getCurrentHeight() / 2, 180);
+ }
+ splashScreen.draw(getGraphics());
+ if (splashScreen.getRotate180()) {
+ getGraphics().endTransform();
+ }
+
+ getGraphics().end();
+ }
+ else
+ {
+ super.render();
+ }
+ }
+ @Override
+ public void resize(int width, int height) {
+ super.resize(width,height);
+ if (splashScreen != null)
+ splashScreen.setSize(width, height);
}
@Override
public void create()
{
//install our error handler
ExceptionHandler.registerErrorHandling();
-
- GuiBase.setIsAndroid(Gdx.app.getType() == Application.ApplicationType.Android);
-
- graphics = new Graphics();
splashScreen = new SplashScreen();
frameRate = new FrameRate();
/*
@@ -101,7 +138,7 @@ class StartAdvanture extends AdventureApplicationAdapter
*/
Gdx.input.setCatchKey(Input.Keys.BACK, true);
destroyThis = true; //Prevent back()
- ForgePreferences prefs = new ForgePreferences();
+ ForgePreferences prefs = SettingsScene.Preference = new ForgePreferences();
String skinName;
if (FileUtil.doesFileExist(ForgeConstants.MAIN_PREFS_FILE)) {
@@ -137,6 +174,7 @@ class StartAdvanture extends AdventureApplicationAdapter
final Localizer localizer = Localizer.getInstance();
//load model on background thread (using progress bar to report progress)
+ super.create();
FThreads.invokeInBackgroundThread(new Runnable() {
@Override
public void run() {
@@ -144,7 +182,7 @@ class StartAdvanture extends AdventureApplicationAdapter
AssetsDownloader.checkForUpdates(splashScreen);
if (exited) { return; } //don't continue if user chose to exit or couldn't download required assets
- FModel.initialize(splashScreen.getProgressBar(), null);
+ FModel.initialize(splashScreen.getProgressBar(),null);
splashScreen.getProgressBar().setDescription(localizer.getMessage("lblLoadingFonts"));
FSkinFont.preloadAll(locale);
@@ -176,8 +214,24 @@ class StartAdvanture extends AdventureApplicationAdapter
SoundSystem.instance.setBackgroundMusic(MusicPlaylist.MENUS); //start background music
destroyThis = false; //Allow back()
Gdx.input.setCatchKey(Input.Keys.MENU, true);
+ //openHomeScreen(-1); //default for startup
splashScreen = null;
+ /*
+ boolean isLandscapeMode = isLandscapeMode();
+ if (isLandscapeMode) { //open preferred new game screen by default if landscape mode
+ NewGameMenu.getPreferredScreen().open();
+ }
+ */
+ //adjust height modifier
+
+ //update landscape mode preference if it doesn't match what the app loaded as
+ if (FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_LANDSCAPE_MODE) != true) {
+ FModel.getPreferences().setPref(ForgePreferences.FPref.UI_LANDSCAPE_MODE, true);
+ FModel.getPreferences().save();
+ }
+
+ ResLoaded();
if (!enablePreloadExtendedArt)
return;
List borderlessCardlistkeys = FileUtil.readFile(ForgeConstants.BORDERLESS_CARD_LIST_FILE);
@@ -198,23 +252,17 @@ class StartAdvanture extends AdventureApplicationAdapter
});
}
});
- super.create();
+
}
+
}
public class Main {
public static void main(String[] args) {
-
-
-
-
-
AdventureApplicationConfiguration config=new AdventureApplicationConfiguration();
-
config.SetPlane("Shandalar");
config.setFullScreen(false);
-
- new Lwjgl3Application(new StartAdvanture(config.Plane), config);
+ new Lwjgl3Application(new StartAdvanture(config.Plane), config );
}
}
diff --git a/forge-adventure/src/main/java/forge/adventure/data/BiomData.java b/forge-adventure/src/main/java/forge/adventure/data/BiomData.java
new file mode 100644
index 00000000000..c46ddedd17c
--- /dev/null
+++ b/forge-adventure/src/main/java/forge/adventure/data/BiomData.java
@@ -0,0 +1,18 @@
+package forge.adventure.data;
+
+import com.badlogic.gdx.graphics.Color;
+
+public class BiomData
+{
+ public double startPointX;
+ public double startPointY;
+ public double noiceWeight;
+ public double distWeight;
+ public String name;
+
+ public double sizeX;
+ public double sizeY;
+ public String color;
+ public boolean invertHeight;
+ public Color GetColor(){return Color.valueOf(color);}
+}
\ No newline at end of file
diff --git a/forge-adventure/src/main/java/forge/adventure/data/WorldData.java b/forge-adventure/src/main/java/forge/adventure/data/WorldData.java
new file mode 100644
index 00000000000..a8b4f9b293a
--- /dev/null
+++ b/forge-adventure/src/main/java/forge/adventure/data/WorldData.java
@@ -0,0 +1,12 @@
+package forge.adventure.data;
+
+import java.util.List;
+public class WorldData
+{
+
+ public int sizeX;
+ public int sizeY;
+
+ public int tileSize;
+ public List bioms;
+}
\ No newline at end of file
diff --git a/forge-adventure/src/main/java/forge/adventure/scene/DuelInput.java b/forge-adventure/src/main/java/forge/adventure/scene/DuelInput.java
index 650672ef6ac..ae1ac89cf03 100644
--- a/forge-adventure/src/main/java/forge/adventure/scene/DuelInput.java
+++ b/forge-adventure/src/main/java/forge/adventure/scene/DuelInput.java
@@ -2,7 +2,6 @@ package forge.adventure.scene;
import com.badlogic.gdx.Input;
import forge.Forge;
-import forge.gamemodes.match.HostedMatch;
import forge.gui.error.BugReporter;
import forge.screens.match.MatchController;
import forge.toolbox.FContainer;
@@ -21,7 +20,7 @@ public class DuelInput extends FGestureAdapter {
private static boolean keyTyped, shiftKeyDown;
private Forge.KeyInputAdapter keyInputAdapter=null;
- public DuelInput(HostedMatch hMatch) {
+ public DuelInput() {
}
@Override
diff --git a/forge-adventure/src/main/java/forge/adventure/scene/DuelScene.java b/forge-adventure/src/main/java/forge/adventure/scene/DuelScene.java
index 30e3bfa1f1b..407a08ca04c 100644
--- a/forge-adventure/src/main/java/forge/adventure/scene/DuelScene.java
+++ b/forge-adventure/src/main/java/forge/adventure/scene/DuelScene.java
@@ -2,22 +2,25 @@ package forge.adventure.scene;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
-import com.badlogic.gdx.scenes.scene2d.Stage;
-import com.badlogic.gdx.utils.viewport.StretchViewport;
import forge.Graphics;
+import forge.adventure.AdventureApplicationAdapter;
+import forge.animation.ForgeAnimation;
+import forge.assets.ImageCache;
import forge.deck.io.DeckSerializer;
import forge.game.GameType;
+import forge.game.player.Player;
import forge.game.player.RegisteredPlayer;
import forge.gamemodes.match.GameLobby;
import forge.gamemodes.match.HostedMatch;
import forge.gamemodes.match.LobbySlotType;
-import forge.gui.GuiBase;
import forge.gui.interfaces.IGuiGame;
import forge.interfaces.IUpdateable;
import forge.player.GamePlayerUtil;
+import forge.player.PlayerControllerHuman;
import forge.screens.FScreen;
import forge.screens.match.MatchController;
import forge.toolbox.FOverlay;
+import forge.trackable.TrackableCollection;
import java.io.File;
import java.util.*;
@@ -26,7 +29,7 @@ public class DuelScene extends Scene implements IUpdateable {
//GameLobby lobby;
FScreen screen;
- Graphics graphics;
+ Graphics localGraphics;
HostedMatch hostedMatch;
public DuelScene() {
@@ -34,7 +37,8 @@ public class DuelScene extends Scene implements IUpdateable {
@Override
public void dispose() {
- Stage.dispose();
+ if(Stage!=null)
+ Stage.dispose();
}
@Override
@@ -49,45 +53,50 @@ public class DuelScene extends Scene implements IUpdateable {
Stage.act(Gdx.graphics.getDeltaTime());
Stage.draw();
*/
+ ImageCache.allowSingleLoad();
+ ForgeAnimation.advanceAll();
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); // Clear the screen.
if(hostedMatch== null || hostedMatch .getGameView()==null)
return;
if (screen==null)
{
- screen = MatchController.getView();
- screen.setSize(IntendedWidth, IntendedHeight);
+ return;
}
- graphics.begin(IntendedWidth, IntendedHeight);
- screen.screenPos.setSize(IntendedWidth, IntendedHeight);
+ localGraphics.begin(AdventureApplicationAdapter.CurrentAdapter.getCurrentWidth(), AdventureApplicationAdapter.CurrentAdapter.getCurrentHeight());
+ screen.screenPos.setSize(AdventureApplicationAdapter.CurrentAdapter.getCurrentWidth(), AdventureApplicationAdapter.CurrentAdapter.getCurrentHeight());
if (screen.getRotate180()) {
- graphics.startRotateTransform(IntendedWidth / 2, IntendedHeight / 2, 180);
+ localGraphics.startRotateTransform(AdventureApplicationAdapter.CurrentAdapter.getCurrentWidth() / 2, AdventureApplicationAdapter.CurrentAdapter.getCurrentHeight() / 2, 180);
}
- screen.draw(graphics);
+ screen.draw(localGraphics);
if (screen.getRotate180()) {
- graphics.endTransform();
+ localGraphics.endTransform();
}
for (FOverlay overlay : FOverlay.getOverlays()) {
if (overlay.isVisibleOnScreen(screen)) {
- overlay.screenPos.setSize(IntendedWidth, IntendedHeight);
- overlay.setSize(IntendedWidth, IntendedHeight); //update overlay sizes as they're rendered
+ overlay.screenPos.setSize(AdventureApplicationAdapter.CurrentAdapter.getCurrentWidth(), AdventureApplicationAdapter.CurrentAdapter.getCurrentHeight());
+ overlay.setSize(AdventureApplicationAdapter.CurrentAdapter.getCurrentWidth(), AdventureApplicationAdapter.CurrentAdapter.getCurrentHeight()); //update overlay sizes as they're rendered
if (overlay.getRotate180()) {
- graphics.startRotateTransform(IntendedWidth / 2, IntendedHeight / 2, 180);
+ localGraphics.startRotateTransform(AdventureApplicationAdapter.CurrentAdapter.getCurrentHeight() / 2, AdventureApplicationAdapter.CurrentAdapter.getCurrentHeight() / 2, 180);
}
- overlay.draw(graphics);
+ overlay.draw(localGraphics);
if (overlay.getRotate180()) {
- graphics.endTransform();
+ localGraphics.endTransform();
}
}
}
- graphics.end();
-
+ localGraphics.end();
//Batch.end();
}
+ public void GameEnd()
+ {
+ }
+
+ private DuelInput duelInput;
@Override
public void Enter()
{
@@ -105,26 +114,37 @@ public class DuelScene extends Scene implements IUpdateable {
final Map guiMap = new HashMap<>();
guiMap.put(humanPlayer, MatchController.instance);
- hostedMatch = GuiBase.getInterface().hostMatch();
+ hostedMatch = MatchController.instance.hostMatch();
+
+ hostedMatch.setEndGameHook(()->GameEnd());
hostedMatch.startMatch(GameType.Constructed, appliedVariants, players, guiMap);
- Gdx.input.setInputProcessor(new DuelInput(hostedMatch));
+ MatchController.instance.setGameView(hostedMatch.getGameView());
+
+
+ for (final Player p : hostedMatch.getGame().getPlayers()) {
+ if (p.getController() instanceof PlayerControllerHuman) {
+ final PlayerControllerHuman humanController = (PlayerControllerHuman) p.getController();
+ humanController.setGui(MatchController.instance);
+ MatchController.instance.setOriginalGameController(p.getView(), humanController);
+ MatchController.instance.openView(new TrackableCollection<>(p.getView()));
+ }
+ }
+
+ screen = MatchController.getView();
+ screen.setHeaderCaption("DUUUUUUUELLL");
+ screen.setSize(AdventureApplicationAdapter.CurrentAdapter.getCurrentWidth(), AdventureApplicationAdapter.CurrentAdapter.getCurrentHeight());
+
+
+ Gdx.input.setInputProcessor(duelInput);
}
- public boolean Resume()
- {
- return true;
- }
- public boolean Exit()
- {
- Gdx.app.exit();
- return true;
- }
+
@Override
public void create() {
- Stage = new Stage(new StretchViewport(IntendedWidth,IntendedHeight));
+ duelInput=new DuelInput();
+ localGraphics= AdventureApplicationAdapter.CurrentAdapter.getGraphics();
//lobby = new LocalLobby();
- graphics=new Graphics();
//initLobby(lobby);
diff --git a/forge-adventure/src/main/java/forge/adventure/scene/NewGameScene.java b/forge-adventure/src/main/java/forge/adventure/scene/NewGameScene.java
index 3800a0a9e5d..e4e929c082c 100644
--- a/forge-adventure/src/main/java/forge/adventure/scene/NewGameScene.java
+++ b/forge-adventure/src/main/java/forge/adventure/scene/NewGameScene.java
@@ -2,13 +2,16 @@ package forge.adventure.scene;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
+import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Texture;
-import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
-import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
-import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
+import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup;
import com.badlogic.gdx.utils.viewport.StretchViewport;
import forge.adventure.AdventureApplicationAdapter;
+import forge.adventure.util.Controls;
+import forge.localinstance.properties.ForgePreferences;
+import forge.model.FModel;
+import forge.adventure.world.WorldSave;
public class NewGameScene extends Scene {
Texture Background;
@@ -22,7 +25,7 @@ public class NewGameScene extends Scene {
Stage.dispose();
Background.dispose();
}
-
+ Texture image;
@Override
public void render() {
@@ -33,6 +36,8 @@ public class NewGameScene extends Scene {
Stage.getBatch().disableBlending();
Stage.getBatch().draw(Background,0,0,IntendedWidth,IntendedHeight);
Stage.getBatch().enableBlending();
+ if(image!=null)
+ Stage.getBatch().draw(image,0,0);
Stage.getBatch().end();
Stage.act(Gdx.graphics.getDeltaTime());
Stage.draw();
@@ -41,51 +46,34 @@ public class NewGameScene extends Scene {
public boolean Start()
{
-
- AdventureApplicationAdapter.CurrentAdapter.SwitchScene(SceneType.GameScene);
+ FModel.getPreferences().setPref(ForgePreferences.FPref.UI_ENABLE_MUSIC,false);
+ //AdventureApplicationAdapter.CurrentAdapter.SwitchScene(SceneType.GameScene);
+ Pixmap img=WorldSave.GenerateNewWorld();
+ image = new Texture(img);
return true;
}
public boolean Back()
{
- AdventureApplicationAdapter.CurrentAdapter.SwitchScene(SceneType.StartScene);
+ AdventureApplicationAdapter.CurrentAdapter.SwitchScene(SceneType.StartScene.instance);
return true;
}
@Override
public void create() {
+ // FModel.getPreferences().setPref(ForgePreferences.FPref.UI_ENABLE_MUSIC,false);
Stage = new Stage(new StretchViewport(IntendedWidth,IntendedHeight));
Background = new Texture(AdventureApplicationAdapter.CurrentAdapter.GetRes().GetFile("img/title_bg.png"));
+ VerticalGroup nameGroup =new VerticalGroup();
- TextButton button = new TextButton("Start",AdventureApplicationAdapter.CurrentAdapter.GetRes().GetSkin()) ;
- button.setPosition(100,600);
- button.setSize(400,150);
- button.addListener(new ClickListener() {
- @Override
- public void clicked(InputEvent event, float x, float y) {
- try {
- Start();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }});
+ nameGroup.addActor(Controls.newTextButton("Start",()->Start()));
+ nameGroup.addActor(Controls.newTextButton("Back",()->Back()));
- Stage.addActor(button);
-
- button = new TextButton("Back",AdventureApplicationAdapter.CurrentAdapter.GetRes().GetSkin()) ;
- button.setPosition(100,400);
- button.setSize(400,150);
- button.addListener(new ClickListener() {
- @Override
- public void clicked(InputEvent event, float x, float y) {
- try {
- Back();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }});
- Stage.addActor(button);
+ nameGroup.addActor(Controls.newTextButton("Start",()->Start()));
+ nameGroup.addActor(Controls.newTextButton("Back",()->Back()));
+ nameGroup.setPosition(900,500);
+ Stage.addActor(nameGroup);
}
}
diff --git a/forge-adventure/src/main/java/forge/adventure/scene/Scene.java b/forge-adventure/src/main/java/forge/adventure/scene/Scene.java
index 3d33e22a455..1a76d3adea3 100644
--- a/forge-adventure/src/main/java/forge/adventure/scene/Scene.java
+++ b/forge-adventure/src/main/java/forge/adventure/scene/Scene.java
@@ -12,7 +12,7 @@ public abstract class Scene implements Disposable {
public static int IntendedWidth = 1920;
public static int IntendedHeight = 1080;
protected com.badlogic.gdx.scenes.scene2d.Stage Stage;
- Scene()
+ public Scene()
{
}
@@ -25,6 +25,9 @@ public abstract class Scene implements Disposable {
return new TextureRegionDrawable(new Texture(AdventureApplicationAdapter.CurrentAdapter.GetRes().GetFile(path)));
}
+ public void ResLoaded()
+ {
+ }
public boolean Leave(){return true;}
public void Enter()
{
diff --git a/forge-adventure/src/main/java/forge/adventure/scene/SceneType.java b/forge-adventure/src/main/java/forge/adventure/scene/SceneType.java
index 7477cd2fbf3..07c997387cf 100644
--- a/forge-adventure/src/main/java/forge/adventure/scene/SceneType.java
+++ b/forge-adventure/src/main/java/forge/adventure/scene/SceneType.java
@@ -1,8 +1,15 @@
package forge.adventure.scene;
+
public enum SceneType {
- StartScene,
- NewGameScene,
- GameScene,
- DuelScene
+ StartScene(new forge.adventure.scene.StartScene()),
+ NewGameScene(new forge.adventure.scene.NewGameScene()),
+ SettingsScene(new forge.adventure.scene.SettingsScene()),
+ GameScene(new forge.adventure.scene.GameScene()),
+ DuelScene(new forge.adventure.scene.DuelScene())
+ ;
+ public final forge.adventure.scene.Scene instance;
+ private SceneType(forge.adventure.scene.Scene scene) {
+ this.instance = scene;
+ }
}
diff --git a/forge-adventure/src/main/java/forge/adventure/scene/SettingsScene.java b/forge-adventure/src/main/java/forge/adventure/scene/SettingsScene.java
new file mode 100644
index 00000000000..59a4a84d8a3
--- /dev/null
+++ b/forge-adventure/src/main/java/forge/adventure/scene/SettingsScene.java
@@ -0,0 +1,137 @@
+package forge.adventure.scene;
+
+import com.badlogic.gdx.Gdx;
+import com.badlogic.gdx.graphics.GL20;
+import com.badlogic.gdx.graphics.Texture;
+import com.badlogic.gdx.scenes.scene2d.Actor;
+import com.badlogic.gdx.scenes.scene2d.Stage;
+import com.badlogic.gdx.scenes.scene2d.ui.CheckBox;
+import com.badlogic.gdx.scenes.scene2d.ui.Label;
+import com.badlogic.gdx.scenes.scene2d.ui.Slider;
+import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup;
+import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
+import com.badlogic.gdx.utils.viewport.StretchViewport;
+import forge.adventure.AdventureApplicationAdapter;
+import forge.adventure.util.Controls;
+import forge.localinstance.properties.ForgePreferences;
+import forge.util.Localizer;
+
+
+public class SettingsScene extends Scene {
+
+
+ static public ForgePreferences Preference;
+ private VerticalGroup settingGroup;
+ private VerticalGroup nameGroup;
+
+ @Override
+ public void dispose() {
+ if(Stage!=null)
+ Stage.dispose();
+ }
+ Texture Background;
+ @Override
+ public void render() {
+
+
+ Gdx.gl.glClearColor(1,0,1,1);
+ Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
+ Stage.getBatch().begin();
+ Stage.getBatch().disableBlending();
+ Stage.getBatch().draw(Background,0,0,IntendedWidth,IntendedHeight);
+ Stage.getBatch().enableBlending();
+ Stage.getBatch().end();
+ Stage.act(Gdx.graphics.getDeltaTime());
+ Stage.draw();
+
+ }
+
+ public boolean Back()
+ {
+ AdventureApplicationAdapter.CurrentAdapter.SwitchScene(AdventureApplicationAdapter.CurrentAdapter.GetLastScene());
+ return true;
+ }
+ private void AddSettingButton(String name, Class type, ForgePreferences.FPref pref, Object[] para)
+ {
+
+
+ Actor control;
+ if (boolean.class.equals(type))
+ {
+ CheckBox box = Controls.newCheckBox("");
+ control =box;
+ box.setChecked(Preference.getPrefBoolean(pref));
+ control.addListener(new ChangeListener() {
+ @Override
+ public void changed(ChangeEvent event, Actor actor)
+ {
+ Preference.setPref(pref, ((CheckBox)actor).isChecked());
+ Preference.save();
+ }
+ });
+
+ }
+ else if (int.class.equals(type))
+ {
+ Slider slide = Controls.newSlider((int)para[0],(int)para[1],1,false);
+ control=slide;
+ slide.setValue(Preference.getPrefInt(pref));
+ slide.addListener(new ChangeListener() {
+ @Override
+ public void changed(ChangeEvent event, Actor actor)
+ {
+ Preference.setPref(pref, String.valueOf((int)((Slider)actor).getValue()));
+ Preference.save();
+ }
+ });
+
+ }
+ else
+ {
+ control=Controls.newLabel("");
+
+ }
+ control.setHeight(40);
+ Label label=Controls.newLabel(name);
+ nameGroup.addActor(label);
+ settingGroup.addActor(control);
+ }
+ @Override
+ public void ResLoaded()
+ {
+ Stage = new Stage(new StretchViewport(IntendedWidth,IntendedHeight));
+ Background = new Texture( forge.adventure.AdventureApplicationAdapter.CurrentAdapter.GetRes().GetFile("img/title_bg.png"));
+ settingGroup=new VerticalGroup();
+ nameGroup =new VerticalGroup();
+ if(Preference==null)
+ {
+ Preference = new ForgePreferences();
+ }
+ Localizer localizer = Localizer.getInstance();
+
+ AddSettingButton("Enable Music", boolean.class,ForgePreferences.FPref.UI_ENABLE_MUSIC, new Object[]{});
+ AddSettingButton(localizer.getMessage("lblCardName"), boolean.class,ForgePreferences.FPref.UI_OVERLAY_CARD_NAME, new Object[]{});
+ AddSettingButton(localizer.getMessage("cbAdjustMusicVolume"), int.class,ForgePreferences.FPref.UI_VOL_MUSIC, new Object[]{0,100});
+ AddSettingButton(localizer.getMessage("cbAdjustSoundsVolume"), int.class,ForgePreferences.FPref.UI_VOL_SOUNDS, new Object[]{0,100});
+ AddSettingButton(localizer.getMessage("lblManaCost"), boolean.class,ForgePreferences.FPref.UI_OVERLAY_CARD_MANA_COST, new Object[]{});
+ AddSettingButton(localizer.getMessage("lblPowerOrToughness"), boolean.class,ForgePreferences.FPref.UI_OVERLAY_CARD_POWER, new Object[]{});
+ AddSettingButton(localizer.getMessage("lblCardID"), boolean.class,ForgePreferences.FPref.UI_OVERLAY_CARD_ID, new Object[]{});
+ AddSettingButton(localizer.getMessage("lblAbilityIcon"), boolean.class,ForgePreferences.FPref.UI_OVERLAY_ABILITY_ICONS, new Object[]{});
+
+
+
+ //settingGroup.pack();
+ // nameGroup.pack();
+ nameGroup.setPosition(130,600);
+ settingGroup.setPosition(500,600);
+
+ nameGroup.addActor(Controls.newTextButton("Return",()->Back()));
+
+ Stage.addActor(settingGroup);
+ Stage.addActor(nameGroup);
+ }
+ @Override
+ public void create() {
+
+ }
+}
diff --git a/forge-adventure/src/main/java/forge/adventure/scene/StartScene.java b/forge-adventure/src/main/java/forge/adventure/scene/StartScene.java
index 3b9757216f5..7b6a7d5be66 100644
--- a/forge-adventure/src/main/java/forge/adventure/scene/StartScene.java
+++ b/forge-adventure/src/main/java/forge/adventure/scene/StartScene.java
@@ -5,11 +5,11 @@ import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
-import com.badlogic.gdx.scenes.scene2d.ui.Button;
-import com.badlogic.gdx.scenes.scene2d.ui.ImageButton;
+import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.utils.viewport.StretchViewport;
import forge.adventure.AdventureApplicationAdapter;
+import forge.adventure.util.Controls;
import java.util.concurrent.Callable;
@@ -47,14 +47,10 @@ public class StartScene extends Scene {
private void AddButton(String name, Callable func, int ypos)
{
-
- ImageButton button = new ImageButton(DrawableImage("img/title_"+name+".png")) ;
- Button.ButtonStyle style=new ImageButton.ImageButtonStyle();
- style.up=DrawableImage("img/title_"+name+".png");
- style.down=DrawableImage("img/title_"+name+"_pressed.png");
- style.over=DrawableImage("img/title_"+name+"_hover.png");
- button.setStyle(style);
- button.setPosition((IntendedWidth/2)-(button.getWidth()/2),ypos);
+ TextButton button = Controls.newTextButton(name) ;
+ button.getLabel().setFontScale(3);
+ button.setPosition(1200,ypos);
+ button.setSize(400,80);
button.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
@@ -68,7 +64,7 @@ public class StartScene extends Scene {
}
public boolean NewGame()
{
- AdventureApplicationAdapter.CurrentAdapter.SwitchScene(SceneType.NewGameScene);
+ AdventureApplicationAdapter.CurrentAdapter.SwitchScene(forge.adventure.scene.SceneType.NewGameScene.instance);
return true;
}
public boolean Load()
@@ -79,6 +75,11 @@ public class StartScene extends Scene {
{
return true;
}
+ public boolean settings()
+ {
+ AdventureApplicationAdapter.CurrentAdapter.SwitchScene(forge.adventure.scene.SceneType.SettingsScene.instance);
+ return true;
+ }
public boolean Exit()
{
Gdx.app.exit();
@@ -90,10 +91,12 @@ public class StartScene extends Scene {
Background = new Texture( AdventureApplicationAdapter.CurrentAdapter.GetRes().GetFile("img/title_bg.png"));
Title = new Texture( AdventureApplicationAdapter.CurrentAdapter.GetRes().GetFile("img/title.png"));
- AddButton("new_game", () -> NewGame(), (IntendedHeight / 6) * 3);
- AddButton("load",() -> Load(),(IntendedHeight/6)*2);
- AddButton("resume",() -> Resume(),(IntendedHeight/6)*1);
- AddButton("exit",() -> Exit(),0);
+ AddButton("new game", () -> NewGame(), 800);
+ AddButton("load",() -> Load(),700);
+ AddButton("save",() -> Load(),600);
+ AddButton("resume",() -> Resume(),500);
+ AddButton("settings",() -> settings(),400);
+ AddButton("exit",() -> Exit(),300);
diff --git a/forge-adventure/src/main/java/forge/adventure/stage/GameStage.java b/forge-adventure/src/main/java/forge/adventure/stage/GameStage.java
index 934f7732480..e6ec680c306 100644
--- a/forge-adventure/src/main/java/forge/adventure/stage/GameStage.java
+++ b/forge-adventure/src/main/java/forge/adventure/stage/GameStage.java
@@ -1,6 +1,7 @@
package forge.adventure.stage;
import com.badlogic.gdx.Input;
+import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.utils.viewport.StretchViewport;
import forge.adventure.AdventureApplicationAdapter;
@@ -15,6 +16,7 @@ public class GameStage extends Stage {
private int playerMovementX;
private int playerMovementY;
private int playerSpeed=6;
+ private Vector2 target;
MobSprite mob;
PlayerSprite player;
public GameStage()
@@ -31,17 +33,33 @@ public class GameStage extends Stage {
public void act(float delta)
{
super.act(delta);
+ if(target!=null)
+ {
+ if(target.xplayer.getX())
+ playerMovementX=+playerSpeed;
+ else
+ playerMovementX=0;
+ if(target.yplayer.getY())
+ playerMovementY=+playerSpeed;
+ else
+ playerMovementY=0;
+ }
player.moveBy(playerMovementX,playerMovementY);
if(player.collideWith(mob))
{
- AdventureApplicationAdapter.CurrentAdapter.SwitchScene(SceneType.DuelScene);
+ AdventureApplicationAdapter.CurrentAdapter.SwitchScene(SceneType.DuelScene.instance);
}
}
+ @Override
public boolean keyDown(int keycode) {
-
+ super.keyDown(keycode);
if(keycode == Input.Keys.LEFT||keycode==Input.Keys.A)//todo config
{
playerMovementX=-playerSpeed;
@@ -61,6 +79,30 @@ public class GameStage extends Stage {
return true;
}
+ @Override
+ public boolean touchDragged(int screenX, int screenY, int pointer)
+ {
+
+ target=this.screenToStageCoordinates(new Vector2((float)screenX, (float)screenY));
+
+ return false;
+ }
+ @Override
+ public boolean touchDown(int screenX, int screenY, int pointer, int button)
+ {
+ target=this.screenToStageCoordinates(new Vector2((float)screenX, (float)screenY));
+
+ return true;
+ }
+
+ @Override
+ public boolean touchUp(int screenX, int screenY, int pointer, int button)
+ {
+ target=null;
+ return true;
+ }
+
+ @Override
public boolean keyUp(int keycode) {
if(keycode == Input.Keys.LEFT||keycode==Input.Keys.A||keycode == Input.Keys.RIGHT||keycode==Input.Keys.D)//todo config
{
diff --git a/forge-adventure/src/main/java/forge/adventure/util/Controls.java b/forge-adventure/src/main/java/forge/adventure/util/Controls.java
new file mode 100644
index 00000000000..4c3832564d2
--- /dev/null
+++ b/forge-adventure/src/main/java/forge/adventure/util/Controls.java
@@ -0,0 +1,63 @@
+package forge.adventure.util;
+
+import com.badlogic.gdx.scenes.scene2d.InputEvent;
+import com.badlogic.gdx.scenes.scene2d.ui.*;
+import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
+import com.badlogic.gdx.utils.Scaling;
+
+import java.util.concurrent.Callable;
+
+public class Controls {
+ private static Skin SelectedSkin=null;
+ public static int DEFAULTHEIGHT=40;
+ static public TextButton newTextButton(String text)
+ {
+ TextButton ret=new TextButton(text,GetSkin());
+
+ return ret;
+ }
+ static public TextButton newTextButton(String text, Callable func)
+ {
+ TextButton ret=new TextButton(text,GetSkin());
+ ret.addListener(new ClickListener(){
+ @Override
+ public void clicked(InputEvent event, float x, float y) {
+ try {
+ func.call();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ });
+
+ return ret;
+ }
+ static public Slider newSlider(float min,float max,float step,boolean vertical)
+ {
+ Slider ret=new Slider(min,max,step,vertical,GetSkin());
+ ret.getStyle().knob.setMinHeight(DEFAULTHEIGHT);
+ return ret;
+ }
+ static public CheckBox newCheckBox(String text)
+ {
+ CheckBox ret=new CheckBox(text,GetSkin());
+ ret.getImage().setScaling(Scaling.fill);
+ ret.getImageCell().size(DEFAULTHEIGHT);
+ return ret;
+ }
+ static public Skin GetSkin() {
+
+ if(SelectedSkin==null)
+ {
+ SelectedSkin=new Skin(Res.CurrentRes.GetFile("skin/uiskin.json"));
+ SelectedSkin.getFont("default-font").getData().setScale(2);
+ }
+ return SelectedSkin;
+ }
+
+ public static Label newLabel(String name) {
+
+ Label ret=new Label(name,GetSkin());
+ return ret;
+ }
+}
diff --git a/forge-adventure/src/main/java/forge/adventure/util/Res.java b/forge-adventure/src/main/java/forge/adventure/util/Res.java
index 2a72df8dd37..31505388019 100644
--- a/forge-adventure/src/main/java/forge/adventure/util/Res.java
+++ b/forge-adventure/src/main/java/forge/adventure/util/Res.java
@@ -1,7 +1,6 @@
package forge.adventure.util;
import com.badlogic.gdx.files.FileHandle;
-import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import forge.gui.GuiBase;
import forge.localinstance.properties.ForgePreferences;
import forge.model.FModel;
@@ -13,8 +12,9 @@ public class Res {
public static Res CurrentRes;
private String Prefix;
private String Lang="en-us";
- private Skin SelectedSkin=null;
private HashMap Cache=new HashMap();
+
+ public String GetPrefix(){return Prefix;}
public Res(String plane) {
CurrentRes=this;
Prefix= GuiBase.getInterface().getAssetsDir()+"/res/adventure/"+plane+"/";
@@ -28,6 +28,7 @@ public class Res {
String fullPath=Prefix+path;
if(!Cache.containsKey(fullPath))
{
+
String fileName = fullPath.replaceFirst("[.][^.]+$", "");
String ext= fullPath.substring(fullPath.lastIndexOf('.'));
String langFile=fileName+"-"+Lang+ext;
@@ -43,10 +44,7 @@ public class Res {
return Cache.get(fullPath);
}
- public Skin GetSkin() {
- if(SelectedSkin==null)
- SelectedSkin=new Skin(GetFile("skin/uiskin.json"));
- return SelectedSkin;
- }
+
+
}
diff --git a/forge-adventure/src/main/java/forge/adventure/world/AdventurePlayer.java b/forge-adventure/src/main/java/forge/adventure/world/AdventurePlayer.java
new file mode 100644
index 00000000000..403fd52cea2
--- /dev/null
+++ b/forge-adventure/src/main/java/forge/adventure/world/AdventurePlayer.java
@@ -0,0 +1,4 @@
+package forge.adventure.world;
+
+public class AdventurePlayer {
+}
diff --git a/forge-adventure/src/main/java/forge/adventure/world/OpenSimplexNoise.java b/forge-adventure/src/main/java/forge/adventure/world/OpenSimplexNoise.java
new file mode 100644
index 00000000000..1b56ea44bcd
--- /dev/null
+++ b/forge-adventure/src/main/java/forge/adventure/world/OpenSimplexNoise.java
@@ -0,0 +1,2429 @@
+package forge.adventure.world;
+
+/*
+ * 2014 OpenSimplex Noise in Java.
+ * by Kurt Spencer
+ *
+ * Updated Dec 2019 and Feb 2020:
+ * - New lattice-symmetric gradient sets
+ * - Optional alternate lattice orientation evaluators
+ *
+ * This implementation has been updated to slightly improve its output, but it is recommented to first
+ * try the newer OpenSimplex2S or OpenSimplex2F noise. These are located in the OpenSimplex2 repo:
+ * https://github.com/KdotJPG/OpenSimplex2
+ *
+ * In the event that the output of this OpenSimplex continues to better fit your project's needs than
+ * either OpenSimplex2 variant, an updated backport of DigitalShadow's optimization is available here:
+ * https://github.com/KdotJPG/OpenSimplex2/blob/master/java/legacy/OpenSimplex.java
+ *
+ * This is mostly kept here for reference. In particular, the 4D code is very slow.
+ */
+
+public class OpenSimplexNoise {
+
+ private static final double STRETCH_CONSTANT_2D = -0.211324865405187; // (1/Math.sqrt(2+1)-1)/2;
+ private static final double SQUISH_CONSTANT_2D = 0.366025403784439; // (Math.sqrt(2+1)-1)/2;
+ private static final double STRETCH_CONSTANT_3D = -1.0 / 6; // (1/Math.sqrt(3+1)-1)/3;
+ private static final double SQUISH_CONSTANT_3D = 1.0 / 3; // (Math.sqrt(3+1)-1)/3;
+ private static final double STRETCH_CONSTANT_4D = -0.138196601125011; // (1/Math.sqrt(4+1)-1)/4;
+ private static final double SQUISH_CONSTANT_4D = 0.309016994374947; // (Math.sqrt(4+1)-1)/4;
+
+ private static final long DEFAULT_SEED = 0;
+
+ private static final int PSIZE = 2048;
+ private static final int PMASK = 2047;
+
+ private short[] perm;
+ private Grad2[] permGrad2;
+ private Grad3[] permGrad3;
+ private Grad4[] permGrad4;
+
+ public OpenSimplexNoise() {
+ this(DEFAULT_SEED);
+ }
+
+ public OpenSimplexNoise(short[] perm) {
+ this.perm = perm;
+ permGrad2 = new Grad2[PSIZE];
+ permGrad3 = new Grad3[PSIZE];
+ permGrad4 = new Grad4[PSIZE];
+
+ for (int i = 0; i < PSIZE; i++) {
+ permGrad2[i] = GRADIENTS_2D[perm[i]];
+ permGrad3[i] = GRADIENTS_3D[perm[i]];
+ permGrad4[i] = GRADIENTS_4D[perm[i]];
+ }
+ }
+
+ public OpenSimplexNoise(long seed) {
+ perm = new short[PSIZE];
+ permGrad2 = new Grad2[PSIZE];
+ permGrad3 = new Grad3[PSIZE];
+ permGrad4 = new Grad4[PSIZE];
+ short[] source = new short[PSIZE];
+ for (short i = 0; i < PSIZE; i++)
+ source[i] = i;
+ for (int i = PSIZE - 1; i >= 0; i--) {
+ seed = seed * 6364136223846793005L + 1442695040888963407L;
+ int r = (int)((seed + 31) % (i + 1));
+ if (r < 0)
+ r += (i + 1);
+ perm[i] = source[r];
+ permGrad2[i] = GRADIENTS_2D[perm[i]];
+ permGrad3[i] = GRADIENTS_3D[perm[i]];
+ permGrad4[i] = GRADIENTS_4D[perm[i]];
+ source[r] = source[i];
+ }
+ }
+
+ // 2D OpenSimplex Noise.
+ public double eval(double x, double y) {
+
+ // Place input coordinates onto grid.
+ double stretchOffset = (x + y) * STRETCH_CONSTANT_2D;
+ double xs = x + stretchOffset;
+ double ys = y + stretchOffset;
+
+ // Floor to get grid coordinates of rhombus (stretched square) super-cell origin.
+ int xsb = fastFloor(xs);
+ int ysb = fastFloor(ys);
+
+ // Compute grid coordinates relative to rhombus origin.
+ double xins = xs - xsb;
+ double yins = ys - ysb;
+
+ // Sum those together to get a value that determines which region we're in.
+ double inSum = xins + yins;
+
+ // Positions relative to origin point.
+ double squishOffsetIns = inSum * SQUISH_CONSTANT_2D;
+ double dx0 = xins + squishOffsetIns;
+ double dy0 = yins + squishOffsetIns;
+
+ // We'll be defining these inside the next block and using them afterwards.
+ double dx_ext, dy_ext;
+ int xsv_ext, ysv_ext;
+
+ double value = 0;
+
+ // Contribution (1,0)
+ double dx1 = dx0 - 1 - SQUISH_CONSTANT_2D;
+ double dy1 = dy0 - 0 - SQUISH_CONSTANT_2D;
+ double attn1 = 2 - dx1 * dx1 - dy1 * dy1;
+ if (attn1 > 0) {
+ attn1 *= attn1;
+ value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, dx1, dy1);
+ }
+
+ // Contribution (0,1)
+ double dx2 = dx0 - 0 - SQUISH_CONSTANT_2D;
+ double dy2 = dy0 - 1 - SQUISH_CONSTANT_2D;
+ double attn2 = 2 - dx2 * dx2 - dy2 * dy2;
+ if (attn2 > 0) {
+ attn2 *= attn2;
+ value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, dx2, dy2);
+ }
+
+ if (inSum <= 1) { // We're inside the triangle (2-Simplex) at (0,0)
+ double zins = 1 - inSum;
+ if (zins > xins || zins > yins) { // (0,0) is one of the closest two triangular vertices
+ if (xins > yins) {
+ xsv_ext = xsb + 1;
+ ysv_ext = ysb - 1;
+ dx_ext = dx0 - 1;
+ dy_ext = dy0 + 1;
+ } else {
+ xsv_ext = xsb - 1;
+ ysv_ext = ysb + 1;
+ dx_ext = dx0 + 1;
+ dy_ext = dy0 - 1;
+ }
+ } else { // (1,0) and (0,1) are the closest two vertices.
+ xsv_ext = xsb + 1;
+ ysv_ext = ysb + 1;
+ dx_ext = dx0 - 1 - 2 * SQUISH_CONSTANT_2D;
+ dy_ext = dy0 - 1 - 2 * SQUISH_CONSTANT_2D;
+ }
+ } else { // We're inside the triangle (2-Simplex) at (1,1)
+ double zins = 2 - inSum;
+ if (zins < xins || zins < yins) { // (0,0) is one of the closest two triangular vertices
+ if (xins > yins) {
+ xsv_ext = xsb + 2;
+ ysv_ext = ysb + 0;
+ dx_ext = dx0 - 2 - 2 * SQUISH_CONSTANT_2D;
+ dy_ext = dy0 + 0 - 2 * SQUISH_CONSTANT_2D;
+ } else {
+ xsv_ext = xsb + 0;
+ ysv_ext = ysb + 2;
+ dx_ext = dx0 + 0 - 2 * SQUISH_CONSTANT_2D;
+ dy_ext = dy0 - 2 - 2 * SQUISH_CONSTANT_2D;
+ }
+ } else { // (1,0) and (0,1) are the closest two vertices.
+ dx_ext = dx0;
+ dy_ext = dy0;
+ xsv_ext = xsb;
+ ysv_ext = ysb;
+ }
+ xsb += 1;
+ ysb += 1;
+ dx0 = dx0 - 1 - 2 * SQUISH_CONSTANT_2D;
+ dy0 = dy0 - 1 - 2 * SQUISH_CONSTANT_2D;
+ }
+
+ // Contribution (0,0) or (1,1)
+ double attn0 = 2 - dx0 * dx0 - dy0 * dy0;
+ if (attn0 > 0) {
+ attn0 *= attn0;
+ value += attn0 * attn0 * extrapolate(xsb, ysb, dx0, dy0);
+ }
+
+ // Extra Vertex
+ double attn_ext = 2 - dx_ext * dx_ext - dy_ext * dy_ext;
+ if (attn_ext > 0) {
+ attn_ext *= attn_ext;
+ value += attn_ext * attn_ext * extrapolate(xsv_ext, ysv_ext, dx_ext, dy_ext);
+ }
+
+ return value;
+ }
+
+ // 3D OpenSimplex Noise.
+ public double eval(double x, double y, double z) {
+
+ // Place input coordinates on simplectic honeycomb.
+ double stretchOffset = (x + y + z) * STRETCH_CONSTANT_3D;
+ double xs = x + stretchOffset;
+ double ys = y + stretchOffset;
+ double zs = z + stretchOffset;
+
+ return eval3_Base(xs, ys, zs);
+ }
+
+ // Not as good as in SuperSimplex/OpenSimplex2S, since there are more visible differences between different slices.
+ // The Z coordinate should always be the "different" coordinate in your use case.
+ public double eval3_XYBeforeZ(double x, double y, double z)
+ {
+ // Combine rotation with skew transform.
+ double xy = x + y;
+ double s2 = xy * 0.211324865405187;
+ double zz = z * 0.288675134594813;
+ double xs = s2 - x + zz, ys = s2 - y + zz;
+ double zs = xy * 0.577350269189626 + zz;
+
+ return eval3_Base(xs, ys, zs);
+ }
+
+ // Similar to the above, except the Y coordinate should always be the "different" coordinate in your use case.
+ public double eval3_XZBeforeY(double x, double y, double z)
+ {
+ // Combine rotation with skew transform.
+ double xz = x + z;
+ double s2 = xz * 0.211324865405187;
+ double yy = y * 0.288675134594813;
+ double xs = s2 - x + yy, zs = s2 - z + yy;
+ double ys = xz * 0.577350269189626 + yy;
+
+ return eval3_Base(xs, ys, zs);
+ }
+
+ // 3D OpenSimplex Noise (base which takes skewed coordinates directly).
+ private double eval3_Base(double xs, double ys, double zs) {
+
+ // Floor to get simplectic honeycomb coordinates of rhombohedron (stretched cube) super-cell origin.
+ int xsb = fastFloor(xs);
+ int ysb = fastFloor(ys);
+ int zsb = fastFloor(zs);
+
+ // Compute simplectic honeycomb coordinates relative to rhombohedral origin.
+ double xins = xs - xsb;
+ double yins = ys - ysb;
+ double zins = zs - zsb;
+
+ // Sum those together to get a value that determines which region we're in.
+ double inSum = xins + yins + zins;
+
+ // Positions relative to origin point.
+ double squishOffsetIns = inSum * SQUISH_CONSTANT_3D;
+ double dx0 = xins + squishOffsetIns;
+ double dy0 = yins + squishOffsetIns;
+ double dz0 = zins + squishOffsetIns;
+
+ // We'll be defining these inside the next block and using them afterwards.
+ double dx_ext0, dy_ext0, dz_ext0;
+ double dx_ext1, dy_ext1, dz_ext1;
+ int xsv_ext0, ysv_ext0, zsv_ext0;
+ int xsv_ext1, ysv_ext1, zsv_ext1;
+
+ double value = 0;
+ if (inSum <= 1) { // We're inside the tetrahedron (3-Simplex) at (0,0,0)
+
+ // Determine which two of (0,0,1), (0,1,0), (1,0,0) are closest.
+ byte aPoint = 0x01;
+ double aScore = xins;
+ byte bPoint = 0x02;
+ double bScore = yins;
+ if (aScore >= bScore && zins > bScore) {
+ bScore = zins;
+ bPoint = 0x04;
+ } else if (aScore < bScore && zins > aScore) {
+ aScore = zins;
+ aPoint = 0x04;
+ }
+
+ // Now we determine the two lattice points not part of the tetrahedron that may contribute.
+ // This depends on the closest two tetrahedral vertices, including (0,0,0)
+ double wins = 1 - inSum;
+ if (wins > aScore || wins > bScore) { // (0,0,0) is one of the closest two tetrahedral vertices.
+ byte c = (bScore > aScore ? bPoint : aPoint); // Our other closest vertex is the closest out of a and b.
+
+ if ((c & 0x01) == 0) {
+ xsv_ext0 = xsb - 1;
+ xsv_ext1 = xsb;
+ dx_ext0 = dx0 + 1;
+ dx_ext1 = dx0;
+ } else {
+ xsv_ext0 = xsv_ext1 = xsb + 1;
+ dx_ext0 = dx_ext1 = dx0 - 1;
+ }
+
+ if ((c & 0x02) == 0) {
+ ysv_ext0 = ysv_ext1 = ysb;
+ dy_ext0 = dy_ext1 = dy0;
+ if ((c & 0x01) == 0) {
+ ysv_ext1 -= 1;
+ dy_ext1 += 1;
+ } else {
+ ysv_ext0 -= 1;
+ dy_ext0 += 1;
+ }
+ } else {
+ ysv_ext0 = ysv_ext1 = ysb + 1;
+ dy_ext0 = dy_ext1 = dy0 - 1;
+ }
+
+ if ((c & 0x04) == 0) {
+ zsv_ext0 = zsb;
+ zsv_ext1 = zsb - 1;
+ dz_ext0 = dz0;
+ dz_ext1 = dz0 + 1;
+ } else {
+ zsv_ext0 = zsv_ext1 = zsb + 1;
+ dz_ext0 = dz_ext1 = dz0 - 1;
+ }
+ } else { // (0,0,0) is not one of the closest two tetrahedral vertices.
+ byte c = (byte)(aPoint | bPoint); // Our two extra vertices are determined by the closest two.
+
+ if ((c & 0x01) == 0) {
+ xsv_ext0 = xsb;
+ xsv_ext1 = xsb - 1;
+ dx_ext0 = dx0 - 2 * SQUISH_CONSTANT_3D;
+ dx_ext1 = dx0 + 1 - SQUISH_CONSTANT_3D;
+ } else {
+ xsv_ext0 = xsv_ext1 = xsb + 1;
+ dx_ext0 = dx0 - 1 - 2 * SQUISH_CONSTANT_3D;
+ dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_3D;
+ }
+
+ if ((c & 0x02) == 0) {
+ ysv_ext0 = ysb;
+ ysv_ext1 = ysb - 1;
+ dy_ext0 = dy0 - 2 * SQUISH_CONSTANT_3D;
+ dy_ext1 = dy0 + 1 - SQUISH_CONSTANT_3D;
+ } else {
+ ysv_ext0 = ysv_ext1 = ysb + 1;
+ dy_ext0 = dy0 - 1 - 2 * SQUISH_CONSTANT_3D;
+ dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_3D;
+ }
+
+ if ((c & 0x04) == 0) {
+ zsv_ext0 = zsb;
+ zsv_ext1 = zsb - 1;
+ dz_ext0 = dz0 - 2 * SQUISH_CONSTANT_3D;
+ dz_ext1 = dz0 + 1 - SQUISH_CONSTANT_3D;
+ } else {
+ zsv_ext0 = zsv_ext1 = zsb + 1;
+ dz_ext0 = dz0 - 1 - 2 * SQUISH_CONSTANT_3D;
+ dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_3D;
+ }
+ }
+
+ // Contribution (0,0,0)
+ double attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0;
+ if (attn0 > 0) {
+ attn0 *= attn0;
+ value += attn0 * attn0 * extrapolate(xsb + 0, ysb + 0, zsb + 0, dx0, dy0, dz0);
+ }
+
+ // Contribution (1,0,0)
+ double dx1 = dx0 - 1 - SQUISH_CONSTANT_3D;
+ double dy1 = dy0 - 0 - SQUISH_CONSTANT_3D;
+ double dz1 = dz0 - 0 - SQUISH_CONSTANT_3D;
+ double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1;
+ if (attn1 > 0) {
+ attn1 *= attn1;
+ value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, zsb + 0, dx1, dy1, dz1);
+ }
+
+ // Contribution (0,1,0)
+ double dx2 = dx0 - 0 - SQUISH_CONSTANT_3D;
+ double dy2 = dy0 - 1 - SQUISH_CONSTANT_3D;
+ double dz2 = dz1;
+ double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2;
+ if (attn2 > 0) {
+ attn2 *= attn2;
+ value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, zsb + 0, dx2, dy2, dz2);
+ }
+
+ // Contribution (0,0,1)
+ double dx3 = dx2;
+ double dy3 = dy1;
+ double dz3 = dz0 - 1 - SQUISH_CONSTANT_3D;
+ double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3;
+ if (attn3 > 0) {
+ attn3 *= attn3;
+ value += attn3 * attn3 * extrapolate(xsb + 0, ysb + 0, zsb + 1, dx3, dy3, dz3);
+ }
+ } else if (inSum >= 2) { // We're inside the tetrahedron (3-Simplex) at (1,1,1)
+
+ // Determine which two tetrahedral vertices are the closest, out of (1,1,0), (1,0,1), (0,1,1) but not (1,1,1).
+ byte aPoint = 0x06;
+ double aScore = xins;
+ byte bPoint = 0x05;
+ double bScore = yins;
+ if (aScore <= bScore && zins < bScore) {
+ bScore = zins;
+ bPoint = 0x03;
+ } else if (aScore > bScore && zins < aScore) {
+ aScore = zins;
+ aPoint = 0x03;
+ }
+
+ // Now we determine the two lattice points not part of the tetrahedron that may contribute.
+ // This depends on the closest two tetrahedral vertices, including (1,1,1)
+ double wins = 3 - inSum;
+ if (wins < aScore || wins < bScore) { // (1,1,1) is one of the closest two tetrahedral vertices.
+ byte c = (bScore < aScore ? bPoint : aPoint); // Our other closest vertex is the closest out of a and b.
+
+ if ((c & 0x01) != 0) {
+ xsv_ext0 = xsb + 2;
+ xsv_ext1 = xsb + 1;
+ dx_ext0 = dx0 - 2 - 3 * SQUISH_CONSTANT_3D;
+ dx_ext1 = dx0 - 1 - 3 * SQUISH_CONSTANT_3D;
+ } else {
+ xsv_ext0 = xsv_ext1 = xsb;
+ dx_ext0 = dx_ext1 = dx0 - 3 * SQUISH_CONSTANT_3D;
+ }
+
+ if ((c & 0x02) != 0) {
+ ysv_ext0 = ysv_ext1 = ysb + 1;
+ dy_ext0 = dy_ext1 = dy0 - 1 - 3 * SQUISH_CONSTANT_3D;
+ if ((c & 0x01) != 0) {
+ ysv_ext1 += 1;
+ dy_ext1 -= 1;
+ } else {
+ ysv_ext0 += 1;
+ dy_ext0 -= 1;
+ }
+ } else {
+ ysv_ext0 = ysv_ext1 = ysb;
+ dy_ext0 = dy_ext1 = dy0 - 3 * SQUISH_CONSTANT_3D;
+ }
+
+ if ((c & 0x04) != 0) {
+ zsv_ext0 = zsb + 1;
+ zsv_ext1 = zsb + 2;
+ dz_ext0 = dz0 - 1 - 3 * SQUISH_CONSTANT_3D;
+ dz_ext1 = dz0 - 2 - 3 * SQUISH_CONSTANT_3D;
+ } else {
+ zsv_ext0 = zsv_ext1 = zsb;
+ dz_ext0 = dz_ext1 = dz0 - 3 * SQUISH_CONSTANT_3D;
+ }
+ } else { // (1,1,1) is not one of the closest two tetrahedral vertices.
+ byte c = (byte)(aPoint & bPoint); // Our two extra vertices are determined by the closest two.
+
+ if ((c & 0x01) != 0) {
+ xsv_ext0 = xsb + 1;
+ xsv_ext1 = xsb + 2;
+ dx_ext0 = dx0 - 1 - SQUISH_CONSTANT_3D;
+ dx_ext1 = dx0 - 2 - 2 * SQUISH_CONSTANT_3D;
+ } else {
+ xsv_ext0 = xsv_ext1 = xsb;
+ dx_ext0 = dx0 - SQUISH_CONSTANT_3D;
+ dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D;
+ }
+
+ if ((c & 0x02) != 0) {
+ ysv_ext0 = ysb + 1;
+ ysv_ext1 = ysb + 2;
+ dy_ext0 = dy0 - 1 - SQUISH_CONSTANT_3D;
+ dy_ext1 = dy0 - 2 - 2 * SQUISH_CONSTANT_3D;
+ } else {
+ ysv_ext0 = ysv_ext1 = ysb;
+ dy_ext0 = dy0 - SQUISH_CONSTANT_3D;
+ dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D;
+ }
+
+ if ((c & 0x04) != 0) {
+ zsv_ext0 = zsb + 1;
+ zsv_ext1 = zsb + 2;
+ dz_ext0 = dz0 - 1 - SQUISH_CONSTANT_3D;
+ dz_ext1 = dz0 - 2 - 2 * SQUISH_CONSTANT_3D;
+ } else {
+ zsv_ext0 = zsv_ext1 = zsb;
+ dz_ext0 = dz0 - SQUISH_CONSTANT_3D;
+ dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D;
+ }
+ }
+
+ // Contribution (1,1,0)
+ double dx3 = dx0 - 1 - 2 * SQUISH_CONSTANT_3D;
+ double dy3 = dy0 - 1 - 2 * SQUISH_CONSTANT_3D;
+ double dz3 = dz0 - 0 - 2 * SQUISH_CONSTANT_3D;
+ double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3;
+ if (attn3 > 0) {
+ attn3 *= attn3;
+ value += attn3 * attn3 * extrapolate(xsb + 1, ysb + 1, zsb + 0, dx3, dy3, dz3);
+ }
+
+ // Contribution (1,0,1)
+ double dx2 = dx3;
+ double dy2 = dy0 - 0 - 2 * SQUISH_CONSTANT_3D;
+ double dz2 = dz0 - 1 - 2 * SQUISH_CONSTANT_3D;
+ double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2;
+ if (attn2 > 0) {
+ attn2 *= attn2;
+ value += attn2 * attn2 * extrapolate(xsb + 1, ysb + 0, zsb + 1, dx2, dy2, dz2);
+ }
+
+ // Contribution (0,1,1)
+ double dx1 = dx0 - 0 - 2 * SQUISH_CONSTANT_3D;
+ double dy1 = dy3;
+ double dz1 = dz2;
+ double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1;
+ if (attn1 > 0) {
+ attn1 *= attn1;
+ value += attn1 * attn1 * extrapolate(xsb + 0, ysb + 1, zsb + 1, dx1, dy1, dz1);
+ }
+
+ // Contribution (1,1,1)
+ dx0 = dx0 - 1 - 3 * SQUISH_CONSTANT_3D;
+ dy0 = dy0 - 1 - 3 * SQUISH_CONSTANT_3D;
+ dz0 = dz0 - 1 - 3 * SQUISH_CONSTANT_3D;
+ double attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0;
+ if (attn0 > 0) {
+ attn0 *= attn0;
+ value += attn0 * attn0 * extrapolate(xsb + 1, ysb + 1, zsb + 1, dx0, dy0, dz0);
+ }
+ } else { // We're inside the octahedron (Rectified 3-Simplex) in between.
+ double aScore;
+ byte aPoint;
+ boolean aIsFurtherSide;
+ double bScore;
+ byte bPoint;
+ boolean bIsFurtherSide;
+
+ // Decide between point (0,0,1) and (1,1,0) as closest
+ double p1 = xins + yins;
+ if (p1 > 1) {
+ aScore = p1 - 1;
+ aPoint = 0x03;
+ aIsFurtherSide = true;
+ } else {
+ aScore = 1 - p1;
+ aPoint = 0x04;
+ aIsFurtherSide = false;
+ }
+
+ // Decide between point (0,1,0) and (1,0,1) as closest
+ double p2 = xins + zins;
+ if (p2 > 1) {
+ bScore = p2 - 1;
+ bPoint = 0x05;
+ bIsFurtherSide = true;
+ } else {
+ bScore = 1 - p2;
+ bPoint = 0x02;
+ bIsFurtherSide = false;
+ }
+
+ // The closest out of the two (1,0,0) and (0,1,1) will replace the furthest out of the two decided above, if closer.
+ double p3 = yins + zins;
+ if (p3 > 1) {
+ double score = p3 - 1;
+ if (aScore <= bScore && aScore < score) {
+ aScore = score;
+ aPoint = 0x06;
+ aIsFurtherSide = true;
+ } else if (aScore > bScore && bScore < score) {
+ bScore = score;
+ bPoint = 0x06;
+ bIsFurtherSide = true;
+ }
+ } else {
+ double score = 1 - p3;
+ if (aScore <= bScore && aScore < score) {
+ aScore = score;
+ aPoint = 0x01;
+ aIsFurtherSide = false;
+ } else if (aScore > bScore && bScore < score) {
+ bScore = score;
+ bPoint = 0x01;
+ bIsFurtherSide = false;
+ }
+ }
+
+ // Where each of the two closest points are determines how the extra two vertices are calculated.
+ if (aIsFurtherSide == bIsFurtherSide) {
+ if (aIsFurtherSide) { // Both closest points on (1,1,1) side
+
+ // One of the two extra points is (1,1,1)
+ dx_ext0 = dx0 - 1 - 3 * SQUISH_CONSTANT_3D;
+ dy_ext0 = dy0 - 1 - 3 * SQUISH_CONSTANT_3D;
+ dz_ext0 = dz0 - 1 - 3 * SQUISH_CONSTANT_3D;
+ xsv_ext0 = xsb + 1;
+ ysv_ext0 = ysb + 1;
+ zsv_ext0 = zsb + 1;
+
+ // Other extra point is based on the shared axis.
+ byte c = (byte)(aPoint & bPoint);
+ if ((c & 0x01) != 0) {
+ dx_ext1 = dx0 - 2 - 2 * SQUISH_CONSTANT_3D;
+ dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D;
+ dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D;
+ xsv_ext1 = xsb + 2;
+ ysv_ext1 = ysb;
+ zsv_ext1 = zsb;
+ } else if ((c & 0x02) != 0) {
+ dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D;
+ dy_ext1 = dy0 - 2 - 2 * SQUISH_CONSTANT_3D;
+ dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D;
+ xsv_ext1 = xsb;
+ ysv_ext1 = ysb + 2;
+ zsv_ext1 = zsb;
+ } else {
+ dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D;
+ dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D;
+ dz_ext1 = dz0 - 2 - 2 * SQUISH_CONSTANT_3D;
+ xsv_ext1 = xsb;
+ ysv_ext1 = ysb;
+ zsv_ext1 = zsb + 2;
+ }
+ } else {// Both closest points on (0,0,0) side
+
+ // One of the two extra points is (0,0,0)
+ dx_ext0 = dx0;
+ dy_ext0 = dy0;
+ dz_ext0 = dz0;
+ xsv_ext0 = xsb;
+ ysv_ext0 = ysb;
+ zsv_ext0 = zsb;
+
+ // Other extra point is based on the omitted axis.
+ byte c = (byte)(aPoint | bPoint);
+ if ((c & 0x01) == 0) {
+ dx_ext1 = dx0 + 1 - SQUISH_CONSTANT_3D;
+ dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_3D;
+ dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_3D;
+ xsv_ext1 = xsb - 1;
+ ysv_ext1 = ysb + 1;
+ zsv_ext1 = zsb + 1;
+ } else if ((c & 0x02) == 0) {
+ dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_3D;
+ dy_ext1 = dy0 + 1 - SQUISH_CONSTANT_3D;
+ dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_3D;
+ xsv_ext1 = xsb + 1;
+ ysv_ext1 = ysb - 1;
+ zsv_ext1 = zsb + 1;
+ } else {
+ dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_3D;
+ dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_3D;
+ dz_ext1 = dz0 + 1 - SQUISH_CONSTANT_3D;
+ xsv_ext1 = xsb + 1;
+ ysv_ext1 = ysb + 1;
+ zsv_ext1 = zsb - 1;
+ }
+ }
+ } else { // One point on (0,0,0) side, one point on (1,1,1) side
+ byte c1, c2;
+ if (aIsFurtherSide) {
+ c1 = aPoint;
+ c2 = bPoint;
+ } else {
+ c1 = bPoint;
+ c2 = aPoint;
+ }
+
+ // One contribution is a permutation of (1,1,-1)
+ if ((c1 & 0x01) == 0) {
+ dx_ext0 = dx0 + 1 - SQUISH_CONSTANT_3D;
+ dy_ext0 = dy0 - 1 - SQUISH_CONSTANT_3D;
+ dz_ext0 = dz0 - 1 - SQUISH_CONSTANT_3D;
+ xsv_ext0 = xsb - 1;
+ ysv_ext0 = ysb + 1;
+ zsv_ext0 = zsb + 1;
+ } else if ((c1 & 0x02) == 0) {
+ dx_ext0 = dx0 - 1 - SQUISH_CONSTANT_3D;
+ dy_ext0 = dy0 + 1 - SQUISH_CONSTANT_3D;
+ dz_ext0 = dz0 - 1 - SQUISH_CONSTANT_3D;
+ xsv_ext0 = xsb + 1;
+ ysv_ext0 = ysb - 1;
+ zsv_ext0 = zsb + 1;
+ } else {
+ dx_ext0 = dx0 - 1 - SQUISH_CONSTANT_3D;
+ dy_ext0 = dy0 - 1 - SQUISH_CONSTANT_3D;
+ dz_ext0 = dz0 + 1 - SQUISH_CONSTANT_3D;
+ xsv_ext0 = xsb + 1;
+ ysv_ext0 = ysb + 1;
+ zsv_ext0 = zsb - 1;
+ }
+
+ // One contribution is a permutation of (0,0,2)
+ dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_3D;
+ dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_3D;
+ dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_3D;
+ xsv_ext1 = xsb;
+ ysv_ext1 = ysb;
+ zsv_ext1 = zsb;
+ if ((c2 & 0x01) != 0) {
+ dx_ext1 -= 2;
+ xsv_ext1 += 2;
+ } else if ((c2 & 0x02) != 0) {
+ dy_ext1 -= 2;
+ ysv_ext1 += 2;
+ } else {
+ dz_ext1 -= 2;
+ zsv_ext1 += 2;
+ }
+ }
+
+ // Contribution (1,0,0)
+ double dx1 = dx0 - 1 - SQUISH_CONSTANT_3D;
+ double dy1 = dy0 - 0 - SQUISH_CONSTANT_3D;
+ double dz1 = dz0 - 0 - SQUISH_CONSTANT_3D;
+ double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1;
+ if (attn1 > 0) {
+ attn1 *= attn1;
+ value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, zsb + 0, dx1, dy1, dz1);
+ }
+
+ // Contribution (0,1,0)
+ double dx2 = dx0 - 0 - SQUISH_CONSTANT_3D;
+ double dy2 = dy0 - 1 - SQUISH_CONSTANT_3D;
+ double dz2 = dz1;
+ double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2;
+ if (attn2 > 0) {
+ attn2 *= attn2;
+ value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, zsb + 0, dx2, dy2, dz2);
+ }
+
+ // Contribution (0,0,1)
+ double dx3 = dx2;
+ double dy3 = dy1;
+ double dz3 = dz0 - 1 - SQUISH_CONSTANT_3D;
+ double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3;
+ if (attn3 > 0) {
+ attn3 *= attn3;
+ value += attn3 * attn3 * extrapolate(xsb + 0, ysb + 0, zsb + 1, dx3, dy3, dz3);
+ }
+
+ // Contribution (1,1,0)
+ double dx4 = dx0 - 1 - 2 * SQUISH_CONSTANT_3D;
+ double dy4 = dy0 - 1 - 2 * SQUISH_CONSTANT_3D;
+ double dz4 = dz0 - 0 - 2 * SQUISH_CONSTANT_3D;
+ double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4;
+ if (attn4 > 0) {
+ attn4 *= attn4;
+ value += attn4 * attn4 * extrapolate(xsb + 1, ysb + 1, zsb + 0, dx4, dy4, dz4);
+ }
+
+ // Contribution (1,0,1)
+ double dx5 = dx4;
+ double dy5 = dy0 - 0 - 2 * SQUISH_CONSTANT_3D;
+ double dz5 = dz0 - 1 - 2 * SQUISH_CONSTANT_3D;
+ double attn5 = 2 - dx5 * dx5 - dy5 * dy5 - dz5 * dz5;
+ if (attn5 > 0) {
+ attn5 *= attn5;
+ value += attn5 * attn5 * extrapolate(xsb + 1, ysb + 0, zsb + 1, dx5, dy5, dz5);
+ }
+
+ // Contribution (0,1,1)
+ double dx6 = dx0 - 0 - 2 * SQUISH_CONSTANT_3D;
+ double dy6 = dy4;
+ double dz6 = dz5;
+ double attn6 = 2 - dx6 * dx6 - dy6 * dy6 - dz6 * dz6;
+ if (attn6 > 0) {
+ attn6 *= attn6;
+ value += attn6 * attn6 * extrapolate(xsb + 0, ysb + 1, zsb + 1, dx6, dy6, dz6);
+ }
+ }
+
+ // First extra vertex
+ double attn_ext0 = 2 - dx_ext0 * dx_ext0 - dy_ext0 * dy_ext0 - dz_ext0 * dz_ext0;
+ if (attn_ext0 > 0)
+ {
+ attn_ext0 *= attn_ext0;
+ value += attn_ext0 * attn_ext0 * extrapolate(xsv_ext0, ysv_ext0, zsv_ext0, dx_ext0, dy_ext0, dz_ext0);
+ }
+
+ // Second extra vertex
+ double attn_ext1 = 2 - dx_ext1 * dx_ext1 - dy_ext1 * dy_ext1 - dz_ext1 * dz_ext1;
+ if (attn_ext1 > 0)
+ {
+ attn_ext1 *= attn_ext1;
+ value += attn_ext1 * attn_ext1 * extrapolate(xsv_ext1, ysv_ext1, zsv_ext1, dx_ext1, dy_ext1, dz_ext1);
+ }
+
+ return value;
+ }
+
+ public double eval(double x, double y, double z, double w) {
+
+ // Get points for A4 lattice
+ double s = -0.138196601125011 * (x + y + z + w);
+ double xs = x + s, ys = y + s, zs = z + s, ws = w + s;
+
+ return eval4_Base(xs, ys, zs, ws);
+ }
+
+ public double eval4_XYBeforeZW(double x, double y, double z, double w) {
+
+ double s2 = (x + y) * -0.178275657951399372 + (z + w) * 0.215623393288842828;
+ double t2 = (z + w) * -0.403949762580207112 + (x + y) * -0.375199083010075342;
+ double xs = x + s2, ys = y + s2, zs = z + t2, ws = w + t2;
+
+ return eval4_Base(xs, ys, zs, ws);
+ }
+
+ public double eval4_XZBeforeYW(double x, double y, double z, double w) {
+
+ double s2 = (x + z) * -0.178275657951399372 + (y + w) * 0.215623393288842828;
+ double t2 = (y + w) * -0.403949762580207112 + (x + z) * -0.375199083010075342;
+ double xs = x + s2, ys = y + t2, zs = z + s2, ws = w + t2;
+
+ return eval4_Base(xs, ys, zs, ws);
+ }
+
+ public double eval4_XYZBeforeW(double x, double y, double z, double w) {
+
+ double xyz = x + y + z;
+ double ww = w * 0.2236067977499788;
+ double s2 = xyz * -0.16666666666666666 + ww;
+ double xs = x + s2, ys = y + s2, zs = z + s2, ws = -0.5 * xyz + ww;
+
+ return eval4_Base(xs, ys, zs, ws);
+ }
+
+ // 4D OpenSimplex Noise.
+ private double eval4_Base(double xs, double ys, double zs, double ws) {
+
+ // Floor to get simplectic honeycomb coordinates of rhombo-hypercube super-cell origin.
+ int xsb = fastFloor(xs);
+ int ysb = fastFloor(ys);
+ int zsb = fastFloor(zs);
+ int wsb = fastFloor(ws);
+
+ // Compute simplectic honeycomb coordinates relative to rhombo-hypercube origin.
+ double xins = xs - xsb;
+ double yins = ys - ysb;
+ double zins = zs - zsb;
+ double wins = ws - wsb;
+
+ // Sum those together to get a value that determines which region we're in.
+ double inSum = xins + yins + zins + wins;
+
+ // Positions relative to origin point.
+ double squishOffsetIns = inSum * SQUISH_CONSTANT_4D;
+ double dx0 = xins + squishOffsetIns;
+ double dy0 = yins + squishOffsetIns;
+ double dz0 = zins + squishOffsetIns;
+ double dw0 = wins + squishOffsetIns;
+
+ // We'll be defining these inside the next block and using them afterwards.
+ double dx_ext0, dy_ext0, dz_ext0, dw_ext0;
+ double dx_ext1, dy_ext1, dz_ext1, dw_ext1;
+ double dx_ext2, dy_ext2, dz_ext2, dw_ext2;
+ int xsv_ext0, ysv_ext0, zsv_ext0, wsv_ext0;
+ int xsv_ext1, ysv_ext1, zsv_ext1, wsv_ext1;
+ int xsv_ext2, ysv_ext2, zsv_ext2, wsv_ext2;
+
+ double value = 0;
+ if (inSum <= 1) { // We're inside the pentachoron (4-Simplex) at (0,0,0,0)
+
+ // Determine which two of (0,0,0,1), (0,0,1,0), (0,1,0,0), (1,0,0,0) are closest.
+ byte aPoint = 0x01;
+ double aScore = xins;
+ byte bPoint = 0x02;
+ double bScore = yins;
+ if (aScore >= bScore && zins > bScore) {
+ bScore = zins;
+ bPoint = 0x04;
+ } else if (aScore < bScore && zins > aScore) {
+ aScore = zins;
+ aPoint = 0x04;
+ }
+ if (aScore >= bScore && wins > bScore) {
+ bScore = wins;
+ bPoint = 0x08;
+ } else if (aScore < bScore && wins > aScore) {
+ aScore = wins;
+ aPoint = 0x08;
+ }
+
+ // Now we determine the three lattice points not part of the pentachoron that may contribute.
+ // This depends on the closest two pentachoron vertices, including (0,0,0,0)
+ double uins = 1 - inSum;
+ if (uins > aScore || uins > bScore) { // (0,0,0,0) is one of the closest two pentachoron vertices.
+ byte c = (bScore > aScore ? bPoint : aPoint); // Our other closest vertex is the closest out of a and b.
+ if ((c & 0x01) == 0) {
+ xsv_ext0 = xsb - 1;
+ xsv_ext1 = xsv_ext2 = xsb;
+ dx_ext0 = dx0 + 1;
+ dx_ext1 = dx_ext2 = dx0;
+ } else {
+ xsv_ext0 = xsv_ext1 = xsv_ext2 = xsb + 1;
+ dx_ext0 = dx_ext1 = dx_ext2 = dx0 - 1;
+ }
+
+ if ((c & 0x02) == 0) {
+ ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb;
+ dy_ext0 = dy_ext1 = dy_ext2 = dy0;
+ if ((c & 0x01) == 0x01) {
+ ysv_ext0 -= 1;
+ dy_ext0 += 1;
+ } else {
+ ysv_ext1 -= 1;
+ dy_ext1 += 1;
+ }
+ } else {
+ ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb + 1;
+ dy_ext0 = dy_ext1 = dy_ext2 = dy0 - 1;
+ }
+
+ if ((c & 0x04) == 0) {
+ zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb;
+ dz_ext0 = dz_ext1 = dz_ext2 = dz0;
+ if ((c & 0x03) != 0) {
+ if ((c & 0x03) == 0x03) {
+ zsv_ext0 -= 1;
+ dz_ext0 += 1;
+ } else {
+ zsv_ext1 -= 1;
+ dz_ext1 += 1;
+ }
+ } else {
+ zsv_ext2 -= 1;
+ dz_ext2 += 1;
+ }
+ } else {
+ zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb + 1;
+ dz_ext0 = dz_ext1 = dz_ext2 = dz0 - 1;
+ }
+
+ if ((c & 0x08) == 0) {
+ wsv_ext0 = wsv_ext1 = wsb;
+ wsv_ext2 = wsb - 1;
+ dw_ext0 = dw_ext1 = dw0;
+ dw_ext2 = dw0 + 1;
+ } else {
+ wsv_ext0 = wsv_ext1 = wsv_ext2 = wsb + 1;
+ dw_ext0 = dw_ext1 = dw_ext2 = dw0 - 1;
+ }
+ } else { // (0,0,0,0) is not one of the closest two pentachoron vertices.
+ byte c = (byte)(aPoint | bPoint); // Our three extra vertices are determined by the closest two.
+
+ if ((c & 0x01) == 0) {
+ xsv_ext0 = xsv_ext2 = xsb;
+ xsv_ext1 = xsb - 1;
+ dx_ext0 = dx0 - 2 * SQUISH_CONSTANT_4D;
+ dx_ext1 = dx0 + 1 - SQUISH_CONSTANT_4D;
+ dx_ext2 = dx0 - SQUISH_CONSTANT_4D;
+ } else {
+ xsv_ext0 = xsv_ext1 = xsv_ext2 = xsb + 1;
+ dx_ext0 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ dx_ext1 = dx_ext2 = dx0 - 1 - SQUISH_CONSTANT_4D;
+ }
+
+ if ((c & 0x02) == 0) {
+ ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb;
+ dy_ext0 = dy0 - 2 * SQUISH_CONSTANT_4D;
+ dy_ext1 = dy_ext2 = dy0 - SQUISH_CONSTANT_4D;
+ if ((c & 0x01) == 0x01) {
+ ysv_ext1 -= 1;
+ dy_ext1 += 1;
+ } else {
+ ysv_ext2 -= 1;
+ dy_ext2 += 1;
+ }
+ } else {
+ ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb + 1;
+ dy_ext0 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ dy_ext1 = dy_ext2 = dy0 - 1 - SQUISH_CONSTANT_4D;
+ }
+
+ if ((c & 0x04) == 0) {
+ zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb;
+ dz_ext0 = dz0 - 2 * SQUISH_CONSTANT_4D;
+ dz_ext1 = dz_ext2 = dz0 - SQUISH_CONSTANT_4D;
+ if ((c & 0x03) == 0x03) {
+ zsv_ext1 -= 1;
+ dz_ext1 += 1;
+ } else {
+ zsv_ext2 -= 1;
+ dz_ext2 += 1;
+ }
+ } else {
+ zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb + 1;
+ dz_ext0 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ dz_ext1 = dz_ext2 = dz0 - 1 - SQUISH_CONSTANT_4D;
+ }
+
+ if ((c & 0x08) == 0) {
+ wsv_ext0 = wsv_ext1 = wsb;
+ wsv_ext2 = wsb - 1;
+ dw_ext0 = dw0 - 2 * SQUISH_CONSTANT_4D;
+ dw_ext1 = dw0 - SQUISH_CONSTANT_4D;
+ dw_ext2 = dw0 + 1 - SQUISH_CONSTANT_4D;
+ } else {
+ wsv_ext0 = wsv_ext1 = wsv_ext2 = wsb + 1;
+ dw_ext0 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ dw_ext1 = dw_ext2 = dw0 - 1 - SQUISH_CONSTANT_4D;
+ }
+ }
+
+ // Contribution (0,0,0,0)
+ double attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0 - dw0 * dw0;
+ if (attn0 > 0) {
+ attn0 *= attn0;
+ value += attn0 * attn0 * extrapolate(xsb + 0, ysb + 0, zsb + 0, wsb + 0, dx0, dy0, dz0, dw0);
+ }
+
+ // Contribution (1,0,0,0)
+ double dx1 = dx0 - 1 - SQUISH_CONSTANT_4D;
+ double dy1 = dy0 - 0 - SQUISH_CONSTANT_4D;
+ double dz1 = dz0 - 0 - SQUISH_CONSTANT_4D;
+ double dw1 = dw0 - 0 - SQUISH_CONSTANT_4D;
+ double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1 - dw1 * dw1;
+ if (attn1 > 0) {
+ attn1 *= attn1;
+ value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, zsb + 0, wsb + 0, dx1, dy1, dz1, dw1);
+ }
+
+ // Contribution (0,1,0,0)
+ double dx2 = dx0 - 0 - SQUISH_CONSTANT_4D;
+ double dy2 = dy0 - 1 - SQUISH_CONSTANT_4D;
+ double dz2 = dz1;
+ double dw2 = dw1;
+ double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2 - dw2 * dw2;
+ if (attn2 > 0) {
+ attn2 *= attn2;
+ value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, zsb + 0, wsb + 0, dx2, dy2, dz2, dw2);
+ }
+
+ // Contribution (0,0,1,0)
+ double dx3 = dx2;
+ double dy3 = dy1;
+ double dz3 = dz0 - 1 - SQUISH_CONSTANT_4D;
+ double dw3 = dw1;
+ double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3 - dw3 * dw3;
+ if (attn3 > 0) {
+ attn3 *= attn3;
+ value += attn3 * attn3 * extrapolate(xsb + 0, ysb + 0, zsb + 1, wsb + 0, dx3, dy3, dz3, dw3);
+ }
+
+ // Contribution (0,0,0,1)
+ double dx4 = dx2;
+ double dy4 = dy1;
+ double dz4 = dz1;
+ double dw4 = dw0 - 1 - SQUISH_CONSTANT_4D;
+ double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4 - dw4 * dw4;
+ if (attn4 > 0) {
+ attn4 *= attn4;
+ value += attn4 * attn4 * extrapolate(xsb + 0, ysb + 0, zsb + 0, wsb + 1, dx4, dy4, dz4, dw4);
+ }
+ } else if (inSum >= 3) { // We're inside the pentachoron (4-Simplex) at (1,1,1,1)
+ // Determine which two of (1,1,1,0), (1,1,0,1), (1,0,1,1), (0,1,1,1) are closest.
+ byte aPoint = 0x0E;
+ double aScore = xins;
+ byte bPoint = 0x0D;
+ double bScore = yins;
+ if (aScore <= bScore && zins < bScore) {
+ bScore = zins;
+ bPoint = 0x0B;
+ } else if (aScore > bScore && zins < aScore) {
+ aScore = zins;
+ aPoint = 0x0B;
+ }
+ if (aScore <= bScore && wins < bScore) {
+ bScore = wins;
+ bPoint = 0x07;
+ } else if (aScore > bScore && wins < aScore) {
+ aScore = wins;
+ aPoint = 0x07;
+ }
+
+ // Now we determine the three lattice points not part of the pentachoron that may contribute.
+ // This depends on the closest two pentachoron vertices, including (0,0,0,0)
+ double uins = 4 - inSum;
+ if (uins < aScore || uins < bScore) { // (1,1,1,1) is one of the closest two pentachoron vertices.
+ byte c = (bScore < aScore ? bPoint : aPoint); // Our other closest vertex is the closest out of a and b.
+
+ if ((c & 0x01) != 0) {
+ xsv_ext0 = xsb + 2;
+ xsv_ext1 = xsv_ext2 = xsb + 1;
+ dx_ext0 = dx0 - 2 - 4 * SQUISH_CONSTANT_4D;
+ dx_ext1 = dx_ext2 = dx0 - 1 - 4 * SQUISH_CONSTANT_4D;
+ } else {
+ xsv_ext0 = xsv_ext1 = xsv_ext2 = xsb;
+ dx_ext0 = dx_ext1 = dx_ext2 = dx0 - 4 * SQUISH_CONSTANT_4D;
+ }
+
+ if ((c & 0x02) != 0) {
+ ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb + 1;
+ dy_ext0 = dy_ext1 = dy_ext2 = dy0 - 1 - 4 * SQUISH_CONSTANT_4D;
+ if ((c & 0x01) != 0) {
+ ysv_ext1 += 1;
+ dy_ext1 -= 1;
+ } else {
+ ysv_ext0 += 1;
+ dy_ext0 -= 1;
+ }
+ } else {
+ ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb;
+ dy_ext0 = dy_ext1 = dy_ext2 = dy0 - 4 * SQUISH_CONSTANT_4D;
+ }
+
+ if ((c & 0x04) != 0) {
+ zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb + 1;
+ dz_ext0 = dz_ext1 = dz_ext2 = dz0 - 1 - 4 * SQUISH_CONSTANT_4D;
+ if ((c & 0x03) != 0x03) {
+ if ((c & 0x03) == 0) {
+ zsv_ext0 += 1;
+ dz_ext0 -= 1;
+ } else {
+ zsv_ext1 += 1;
+ dz_ext1 -= 1;
+ }
+ } else {
+ zsv_ext2 += 1;
+ dz_ext2 -= 1;
+ }
+ } else {
+ zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb;
+ dz_ext0 = dz_ext1 = dz_ext2 = dz0 - 4 * SQUISH_CONSTANT_4D;
+ }
+
+ if ((c & 0x08) != 0) {
+ wsv_ext0 = wsv_ext1 = wsb + 1;
+ wsv_ext2 = wsb + 2;
+ dw_ext0 = dw_ext1 = dw0 - 1 - 4 * SQUISH_CONSTANT_4D;
+ dw_ext2 = dw0 - 2 - 4 * SQUISH_CONSTANT_4D;
+ } else {
+ wsv_ext0 = wsv_ext1 = wsv_ext2 = wsb;
+ dw_ext0 = dw_ext1 = dw_ext2 = dw0 - 4 * SQUISH_CONSTANT_4D;
+ }
+ } else { // (1,1,1,1) is not one of the closest two pentachoron vertices.
+ byte c = (byte)(aPoint & bPoint); // Our three extra vertices are determined by the closest two.
+
+ if ((c & 0x01) != 0) {
+ xsv_ext0 = xsv_ext2 = xsb + 1;
+ xsv_ext1 = xsb + 2;
+ dx_ext0 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ dx_ext1 = dx0 - 2 - 3 * SQUISH_CONSTANT_4D;
+ dx_ext2 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D;
+ } else {
+ xsv_ext0 = xsv_ext1 = xsv_ext2 = xsb;
+ dx_ext0 = dx0 - 2 * SQUISH_CONSTANT_4D;
+ dx_ext1 = dx_ext2 = dx0 - 3 * SQUISH_CONSTANT_4D;
+ }
+
+ if ((c & 0x02) != 0) {
+ ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb + 1;
+ dy_ext0 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ dy_ext1 = dy_ext2 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D;
+ if ((c & 0x01) != 0) {
+ ysv_ext2 += 1;
+ dy_ext2 -= 1;
+ } else {
+ ysv_ext1 += 1;
+ dy_ext1 -= 1;
+ }
+ } else {
+ ysv_ext0 = ysv_ext1 = ysv_ext2 = ysb;
+ dy_ext0 = dy0 - 2 * SQUISH_CONSTANT_4D;
+ dy_ext1 = dy_ext2 = dy0 - 3 * SQUISH_CONSTANT_4D;
+ }
+
+ if ((c & 0x04) != 0) {
+ zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb + 1;
+ dz_ext0 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ dz_ext1 = dz_ext2 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D;
+ if ((c & 0x03) != 0) {
+ zsv_ext2 += 1;
+ dz_ext2 -= 1;
+ } else {
+ zsv_ext1 += 1;
+ dz_ext1 -= 1;
+ }
+ } else {
+ zsv_ext0 = zsv_ext1 = zsv_ext2 = zsb;
+ dz_ext0 = dz0 - 2 * SQUISH_CONSTANT_4D;
+ dz_ext1 = dz_ext2 = dz0 - 3 * SQUISH_CONSTANT_4D;
+ }
+
+ if ((c & 0x08) != 0) {
+ wsv_ext0 = wsv_ext1 = wsb + 1;
+ wsv_ext2 = wsb + 2;
+ dw_ext0 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ dw_ext1 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D;
+ dw_ext2 = dw0 - 2 - 3 * SQUISH_CONSTANT_4D;
+ } else {
+ wsv_ext0 = wsv_ext1 = wsv_ext2 = wsb;
+ dw_ext0 = dw0 - 2 * SQUISH_CONSTANT_4D;
+ dw_ext1 = dw_ext2 = dw0 - 3 * SQUISH_CONSTANT_4D;
+ }
+ }
+
+ // Contribution (1,1,1,0)
+ double dx4 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D;
+ double dy4 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D;
+ double dz4 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D;
+ double dw4 = dw0 - 3 * SQUISH_CONSTANT_4D;
+ double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4 - dw4 * dw4;
+ if (attn4 > 0) {
+ attn4 *= attn4;
+ value += attn4 * attn4 * extrapolate(xsb + 1, ysb + 1, zsb + 1, wsb + 0, dx4, dy4, dz4, dw4);
+ }
+
+ // Contribution (1,1,0,1)
+ double dx3 = dx4;
+ double dy3 = dy4;
+ double dz3 = dz0 - 3 * SQUISH_CONSTANT_4D;
+ double dw3 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D;
+ double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3 - dw3 * dw3;
+ if (attn3 > 0) {
+ attn3 *= attn3;
+ value += attn3 * attn3 * extrapolate(xsb + 1, ysb + 1, zsb + 0, wsb + 1, dx3, dy3, dz3, dw3);
+ }
+
+ // Contribution (1,0,1,1)
+ double dx2 = dx4;
+ double dy2 = dy0 - 3 * SQUISH_CONSTANT_4D;
+ double dz2 = dz4;
+ double dw2 = dw3;
+ double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2 - dw2 * dw2;
+ if (attn2 > 0) {
+ attn2 *= attn2;
+ value += attn2 * attn2 * extrapolate(xsb + 1, ysb + 0, zsb + 1, wsb + 1, dx2, dy2, dz2, dw2);
+ }
+
+ // Contribution (0,1,1,1)
+ double dx1 = dx0 - 3 * SQUISH_CONSTANT_4D;
+ double dz1 = dz4;
+ double dy1 = dy4;
+ double dw1 = dw3;
+ double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1 - dw1 * dw1;
+ if (attn1 > 0) {
+ attn1 *= attn1;
+ value += attn1 * attn1 * extrapolate(xsb + 0, ysb + 1, zsb + 1, wsb + 1, dx1, dy1, dz1, dw1);
+ }
+
+ // Contribution (1,1,1,1)
+ dx0 = dx0 - 1 - 4 * SQUISH_CONSTANT_4D;
+ dy0 = dy0 - 1 - 4 * SQUISH_CONSTANT_4D;
+ dz0 = dz0 - 1 - 4 * SQUISH_CONSTANT_4D;
+ dw0 = dw0 - 1 - 4 * SQUISH_CONSTANT_4D;
+ double attn0 = 2 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0 - dw0 * dw0;
+ if (attn0 > 0) {
+ attn0 *= attn0;
+ value += attn0 * attn0 * extrapolate(xsb + 1, ysb + 1, zsb + 1, wsb + 1, dx0, dy0, dz0, dw0);
+ }
+ } else if (inSum <= 2) { // We're inside the first dispentachoron (Rectified 4-Simplex)
+ double aScore;
+ byte aPoint;
+ boolean aIsBiggerSide = true;
+ double bScore;
+ byte bPoint;
+ boolean bIsBiggerSide = true;
+
+ // Decide between (1,1,0,0) and (0,0,1,1)
+ if (xins + yins > zins + wins) {
+ aScore = xins + yins;
+ aPoint = 0x03;
+ } else {
+ aScore = zins + wins;
+ aPoint = 0x0C;
+ }
+
+ // Decide between (1,0,1,0) and (0,1,0,1)
+ if (xins + zins > yins + wins) {
+ bScore = xins + zins;
+ bPoint = 0x05;
+ } else {
+ bScore = yins + wins;
+ bPoint = 0x0A;
+ }
+
+ // Closer between (1,0,0,1) and (0,1,1,0) will replace the further of a and b, if closer.
+ if (xins + wins > yins + zins) {
+ double score = xins + wins;
+ if (aScore >= bScore && score > bScore) {
+ bScore = score;
+ bPoint = 0x09;
+ } else if (aScore < bScore && score > aScore) {
+ aScore = score;
+ aPoint = 0x09;
+ }
+ } else {
+ double score = yins + zins;
+ if (aScore >= bScore && score > bScore) {
+ bScore = score;
+ bPoint = 0x06;
+ } else if (aScore < bScore && score > aScore) {
+ aScore = score;
+ aPoint = 0x06;
+ }
+ }
+
+ // Decide if (1,0,0,0) is closer.
+ double p1 = 2 - inSum + xins;
+ if (aScore >= bScore && p1 > bScore) {
+ bScore = p1;
+ bPoint = 0x01;
+ bIsBiggerSide = false;
+ } else if (aScore < bScore && p1 > aScore) {
+ aScore = p1;
+ aPoint = 0x01;
+ aIsBiggerSide = false;
+ }
+
+ // Decide if (0,1,0,0) is closer.
+ double p2 = 2 - inSum + yins;
+ if (aScore >= bScore && p2 > bScore) {
+ bScore = p2;
+ bPoint = 0x02;
+ bIsBiggerSide = false;
+ } else if (aScore < bScore && p2 > aScore) {
+ aScore = p2;
+ aPoint = 0x02;
+ aIsBiggerSide = false;
+ }
+
+ // Decide if (0,0,1,0) is closer.
+ double p3 = 2 - inSum + zins;
+ if (aScore >= bScore && p3 > bScore) {
+ bScore = p3;
+ bPoint = 0x04;
+ bIsBiggerSide = false;
+ } else if (aScore < bScore && p3 > aScore) {
+ aScore = p3;
+ aPoint = 0x04;
+ aIsBiggerSide = false;
+ }
+
+ // Decide if (0,0,0,1) is closer.
+ double p4 = 2 - inSum + wins;
+ if (aScore >= bScore && p4 > bScore) {
+ bScore = p4;
+ bPoint = 0x08;
+ bIsBiggerSide = false;
+ } else if (aScore < bScore && p4 > aScore) {
+ aScore = p4;
+ aPoint = 0x08;
+ aIsBiggerSide = false;
+ }
+
+ // Where each of the two closest points are determines how the extra three vertices are calculated.
+ if (aIsBiggerSide == bIsBiggerSide) {
+ if (aIsBiggerSide) { // Both closest points on the bigger side
+ byte c1 = (byte)(aPoint | bPoint);
+ byte c2 = (byte)(aPoint & bPoint);
+ if ((c1 & 0x01) == 0) {
+ xsv_ext0 = xsb;
+ xsv_ext1 = xsb - 1;
+ dx_ext0 = dx0 - 3 * SQUISH_CONSTANT_4D;
+ dx_ext1 = dx0 + 1 - 2 * SQUISH_CONSTANT_4D;
+ } else {
+ xsv_ext0 = xsv_ext1 = xsb + 1;
+ dx_ext0 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D;
+ dx_ext1 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ }
+
+ if ((c1 & 0x02) == 0) {
+ ysv_ext0 = ysb;
+ ysv_ext1 = ysb - 1;
+ dy_ext0 = dy0 - 3 * SQUISH_CONSTANT_4D;
+ dy_ext1 = dy0 + 1 - 2 * SQUISH_CONSTANT_4D;
+ } else {
+ ysv_ext0 = ysv_ext1 = ysb + 1;
+ dy_ext0 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D;
+ dy_ext1 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ }
+
+ if ((c1 & 0x04) == 0) {
+ zsv_ext0 = zsb;
+ zsv_ext1 = zsb - 1;
+ dz_ext0 = dz0 - 3 * SQUISH_CONSTANT_4D;
+ dz_ext1 = dz0 + 1 - 2 * SQUISH_CONSTANT_4D;
+ } else {
+ zsv_ext0 = zsv_ext1 = zsb + 1;
+ dz_ext0 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D;
+ dz_ext1 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ }
+
+ if ((c1 & 0x08) == 0) {
+ wsv_ext0 = wsb;
+ wsv_ext1 = wsb - 1;
+ dw_ext0 = dw0 - 3 * SQUISH_CONSTANT_4D;
+ dw_ext1 = dw0 + 1 - 2 * SQUISH_CONSTANT_4D;
+ } else {
+ wsv_ext0 = wsv_ext1 = wsb + 1;
+ dw_ext0 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D;
+ dw_ext1 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ }
+
+ // One combination is a permutation of (0,0,0,2) based on c2
+ xsv_ext2 = xsb;
+ ysv_ext2 = ysb;
+ zsv_ext2 = zsb;
+ wsv_ext2 = wsb;
+ dx_ext2 = dx0 - 2 * SQUISH_CONSTANT_4D;
+ dy_ext2 = dy0 - 2 * SQUISH_CONSTANT_4D;
+ dz_ext2 = dz0 - 2 * SQUISH_CONSTANT_4D;
+ dw_ext2 = dw0 - 2 * SQUISH_CONSTANT_4D;
+ if ((c2 & 0x01) != 0) {
+ xsv_ext2 += 2;
+ dx_ext2 -= 2;
+ } else if ((c2 & 0x02) != 0) {
+ ysv_ext2 += 2;
+ dy_ext2 -= 2;
+ } else if ((c2 & 0x04) != 0) {
+ zsv_ext2 += 2;
+ dz_ext2 -= 2;
+ } else {
+ wsv_ext2 += 2;
+ dw_ext2 -= 2;
+ }
+
+ } else { // Both closest points on the smaller side
+ // One of the two extra points is (0,0,0,0)
+ xsv_ext2 = xsb;
+ ysv_ext2 = ysb;
+ zsv_ext2 = zsb;
+ wsv_ext2 = wsb;
+ dx_ext2 = dx0;
+ dy_ext2 = dy0;
+ dz_ext2 = dz0;
+ dw_ext2 = dw0;
+
+ // Other two points are based on the omitted axes.
+ byte c = (byte)(aPoint | bPoint);
+
+ if ((c & 0x01) == 0) {
+ xsv_ext0 = xsb - 1;
+ xsv_ext1 = xsb;
+ dx_ext0 = dx0 + 1 - SQUISH_CONSTANT_4D;
+ dx_ext1 = dx0 - SQUISH_CONSTANT_4D;
+ } else {
+ xsv_ext0 = xsv_ext1 = xsb + 1;
+ dx_ext0 = dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_4D;
+ }
+
+ if ((c & 0x02) == 0) {
+ ysv_ext0 = ysv_ext1 = ysb;
+ dy_ext0 = dy_ext1 = dy0 - SQUISH_CONSTANT_4D;
+ if ((c & 0x01) == 0x01)
+ {
+ ysv_ext0 -= 1;
+ dy_ext0 += 1;
+ } else {
+ ysv_ext1 -= 1;
+ dy_ext1 += 1;
+ }
+ } else {
+ ysv_ext0 = ysv_ext1 = ysb + 1;
+ dy_ext0 = dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_4D;
+ }
+
+ if ((c & 0x04) == 0) {
+ zsv_ext0 = zsv_ext1 = zsb;
+ dz_ext0 = dz_ext1 = dz0 - SQUISH_CONSTANT_4D;
+ if ((c & 0x03) == 0x03)
+ {
+ zsv_ext0 -= 1;
+ dz_ext0 += 1;
+ } else {
+ zsv_ext1 -= 1;
+ dz_ext1 += 1;
+ }
+ } else {
+ zsv_ext0 = zsv_ext1 = zsb + 1;
+ dz_ext0 = dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_4D;
+ }
+
+ if ((c & 0x08) == 0)
+ {
+ wsv_ext0 = wsb;
+ wsv_ext1 = wsb - 1;
+ dw_ext0 = dw0 - SQUISH_CONSTANT_4D;
+ dw_ext1 = dw0 + 1 - SQUISH_CONSTANT_4D;
+ } else {
+ wsv_ext0 = wsv_ext1 = wsb + 1;
+ dw_ext0 = dw_ext1 = dw0 - 1 - SQUISH_CONSTANT_4D;
+ }
+
+ }
+ } else { // One point on each "side"
+ byte c1, c2;
+ if (aIsBiggerSide) {
+ c1 = aPoint;
+ c2 = bPoint;
+ } else {
+ c1 = bPoint;
+ c2 = aPoint;
+ }
+
+ // Two contributions are the bigger-sided point with each 0 replaced with -1.
+ if ((c1 & 0x01) == 0) {
+ xsv_ext0 = xsb - 1;
+ xsv_ext1 = xsb;
+ dx_ext0 = dx0 + 1 - SQUISH_CONSTANT_4D;
+ dx_ext1 = dx0 - SQUISH_CONSTANT_4D;
+ } else {
+ xsv_ext0 = xsv_ext1 = xsb + 1;
+ dx_ext0 = dx_ext1 = dx0 - 1 - SQUISH_CONSTANT_4D;
+ }
+
+ if ((c1 & 0x02) == 0) {
+ ysv_ext0 = ysv_ext1 = ysb;
+ dy_ext0 = dy_ext1 = dy0 - SQUISH_CONSTANT_4D;
+ if ((c1 & 0x01) == 0x01) {
+ ysv_ext0 -= 1;
+ dy_ext0 += 1;
+ } else {
+ ysv_ext1 -= 1;
+ dy_ext1 += 1;
+ }
+ } else {
+ ysv_ext0 = ysv_ext1 = ysb + 1;
+ dy_ext0 = dy_ext1 = dy0 - 1 - SQUISH_CONSTANT_4D;
+ }
+
+ if ((c1 & 0x04) == 0) {
+ zsv_ext0 = zsv_ext1 = zsb;
+ dz_ext0 = dz_ext1 = dz0 - SQUISH_CONSTANT_4D;
+ if ((c1 & 0x03) == 0x03) {
+ zsv_ext0 -= 1;
+ dz_ext0 += 1;
+ } else {
+ zsv_ext1 -= 1;
+ dz_ext1 += 1;
+ }
+ } else {
+ zsv_ext0 = zsv_ext1 = zsb + 1;
+ dz_ext0 = dz_ext1 = dz0 - 1 - SQUISH_CONSTANT_4D;
+ }
+
+ if ((c1 & 0x08) == 0) {
+ wsv_ext0 = wsb;
+ wsv_ext1 = wsb - 1;
+ dw_ext0 = dw0 - SQUISH_CONSTANT_4D;
+ dw_ext1 = dw0 + 1 - SQUISH_CONSTANT_4D;
+ } else {
+ wsv_ext0 = wsv_ext1 = wsb + 1;
+ dw_ext0 = dw_ext1 = dw0 - 1 - SQUISH_CONSTANT_4D;
+ }
+
+ // One contribution is a permutation of (0,0,0,2) based on the smaller-sided point
+ xsv_ext2 = xsb;
+ ysv_ext2 = ysb;
+ zsv_ext2 = zsb;
+ wsv_ext2 = wsb;
+ dx_ext2 = dx0 - 2 * SQUISH_CONSTANT_4D;
+ dy_ext2 = dy0 - 2 * SQUISH_CONSTANT_4D;
+ dz_ext2 = dz0 - 2 * SQUISH_CONSTANT_4D;
+ dw_ext2 = dw0 - 2 * SQUISH_CONSTANT_4D;
+ if ((c2 & 0x01) != 0) {
+ xsv_ext2 += 2;
+ dx_ext2 -= 2;
+ } else if ((c2 & 0x02) != 0) {
+ ysv_ext2 += 2;
+ dy_ext2 -= 2;
+ } else if ((c2 & 0x04) != 0) {
+ zsv_ext2 += 2;
+ dz_ext2 -= 2;
+ } else {
+ wsv_ext2 += 2;
+ dw_ext2 -= 2;
+ }
+ }
+
+ // Contribution (1,0,0,0)
+ double dx1 = dx0 - 1 - SQUISH_CONSTANT_4D;
+ double dy1 = dy0 - 0 - SQUISH_CONSTANT_4D;
+ double dz1 = dz0 - 0 - SQUISH_CONSTANT_4D;
+ double dw1 = dw0 - 0 - SQUISH_CONSTANT_4D;
+ double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1 - dw1 * dw1;
+ if (attn1 > 0) {
+ attn1 *= attn1;
+ value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, zsb + 0, wsb + 0, dx1, dy1, dz1, dw1);
+ }
+
+ // Contribution (0,1,0,0)
+ double dx2 = dx0 - 0 - SQUISH_CONSTANT_4D;
+ double dy2 = dy0 - 1 - SQUISH_CONSTANT_4D;
+ double dz2 = dz1;
+ double dw2 = dw1;
+ double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2 - dw2 * dw2;
+ if (attn2 > 0) {
+ attn2 *= attn2;
+ value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, zsb + 0, wsb + 0, dx2, dy2, dz2, dw2);
+ }
+
+ // Contribution (0,0,1,0)
+ double dx3 = dx2;
+ double dy3 = dy1;
+ double dz3 = dz0 - 1 - SQUISH_CONSTANT_4D;
+ double dw3 = dw1;
+ double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3 - dw3 * dw3;
+ if (attn3 > 0) {
+ attn3 *= attn3;
+ value += attn3 * attn3 * extrapolate(xsb + 0, ysb + 0, zsb + 1, wsb + 0, dx3, dy3, dz3, dw3);
+ }
+
+ // Contribution (0,0,0,1)
+ double dx4 = dx2;
+ double dy4 = dy1;
+ double dz4 = dz1;
+ double dw4 = dw0 - 1 - SQUISH_CONSTANT_4D;
+ double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4 - dw4 * dw4;
+ if (attn4 > 0) {
+ attn4 *= attn4;
+ value += attn4 * attn4 * extrapolate(xsb + 0, ysb + 0, zsb + 0, wsb + 1, dx4, dy4, dz4, dw4);
+ }
+
+ // Contribution (1,1,0,0)
+ double dx5 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ double dy5 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ double dz5 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D;
+ double dw5 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D;
+ double attn5 = 2 - dx5 * dx5 - dy5 * dy5 - dz5 * dz5 - dw5 * dw5;
+ if (attn5 > 0) {
+ attn5 *= attn5;
+ value += attn5 * attn5 * extrapolate(xsb + 1, ysb + 1, zsb + 0, wsb + 0, dx5, dy5, dz5, dw5);
+ }
+
+ // Contribution (1,0,1,0)
+ double dx6 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ double dy6 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D;
+ double dz6 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ double dw6 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D;
+ double attn6 = 2 - dx6 * dx6 - dy6 * dy6 - dz6 * dz6 - dw6 * dw6;
+ if (attn6 > 0) {
+ attn6 *= attn6;
+ value += attn6 * attn6 * extrapolate(xsb + 1, ysb + 0, zsb + 1, wsb + 0, dx6, dy6, dz6, dw6);
+ }
+
+ // Contribution (1,0,0,1)
+ double dx7 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ double dy7 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D;
+ double dz7 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D;
+ double dw7 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ double attn7 = 2 - dx7 * dx7 - dy7 * dy7 - dz7 * dz7 - dw7 * dw7;
+ if (attn7 > 0) {
+ attn7 *= attn7;
+ value += attn7 * attn7 * extrapolate(xsb + 1, ysb + 0, zsb + 0, wsb + 1, dx7, dy7, dz7, dw7);
+ }
+
+ // Contribution (0,1,1,0)
+ double dx8 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D;
+ double dy8 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ double dz8 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ double dw8 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D;
+ double attn8 = 2 - dx8 * dx8 - dy8 * dy8 - dz8 * dz8 - dw8 * dw8;
+ if (attn8 > 0) {
+ attn8 *= attn8;
+ value += attn8 * attn8 * extrapolate(xsb + 0, ysb + 1, zsb + 1, wsb + 0, dx8, dy8, dz8, dw8);
+ }
+
+ // Contribution (0,1,0,1)
+ double dx9 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D;
+ double dy9 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ double dz9 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D;
+ double dw9 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ double attn9 = 2 - dx9 * dx9 - dy9 * dy9 - dz9 * dz9 - dw9 * dw9;
+ if (attn9 > 0) {
+ attn9 *= attn9;
+ value += attn9 * attn9 * extrapolate(xsb + 0, ysb + 1, zsb + 0, wsb + 1, dx9, dy9, dz9, dw9);
+ }
+
+ // Contribution (0,0,1,1)
+ double dx10 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D;
+ double dy10 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D;
+ double dz10 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ double dw10 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ double attn10 = 2 - dx10 * dx10 - dy10 * dy10 - dz10 * dz10 - dw10 * dw10;
+ if (attn10 > 0) {
+ attn10 *= attn10;
+ value += attn10 * attn10 * extrapolate(xsb + 0, ysb + 0, zsb + 1, wsb + 1, dx10, dy10, dz10, dw10);
+ }
+ } else { // We're inside the second dispentachoron (Rectified 4-Simplex)
+ double aScore;
+ byte aPoint;
+ boolean aIsBiggerSide = true;
+ double bScore;
+ byte bPoint;
+ boolean bIsBiggerSide = true;
+
+ // Decide between (0,0,1,1) and (1,1,0,0)
+ if (xins + yins < zins + wins) {
+ aScore = xins + yins;
+ aPoint = 0x0C;
+ } else {
+ aScore = zins + wins;
+ aPoint = 0x03;
+ }
+
+ // Decide between (0,1,0,1) and (1,0,1,0)
+ if (xins + zins < yins + wins) {
+ bScore = xins + zins;
+ bPoint = 0x0A;
+ } else {
+ bScore = yins + wins;
+ bPoint = 0x05;
+ }
+
+ // Closer between (0,1,1,0) and (1,0,0,1) will replace the further of a and b, if closer.
+ if (xins + wins < yins + zins) {
+ double score = xins + wins;
+ if (aScore <= bScore && score < bScore) {
+ bScore = score;
+ bPoint = 0x06;
+ } else if (aScore > bScore && score < aScore) {
+ aScore = score;
+ aPoint = 0x06;
+ }
+ } else {
+ double score = yins + zins;
+ if (aScore <= bScore && score < bScore) {
+ bScore = score;
+ bPoint = 0x09;
+ } else if (aScore > bScore && score < aScore) {
+ aScore = score;
+ aPoint = 0x09;
+ }
+ }
+
+ // Decide if (0,1,1,1) is closer.
+ double p1 = 3 - inSum + xins;
+ if (aScore <= bScore && p1 < bScore) {
+ bScore = p1;
+ bPoint = 0x0E;
+ bIsBiggerSide = false;
+ } else if (aScore > bScore && p1 < aScore) {
+ aScore = p1;
+ aPoint = 0x0E;
+ aIsBiggerSide = false;
+ }
+
+ // Decide if (1,0,1,1) is closer.
+ double p2 = 3 - inSum + yins;
+ if (aScore <= bScore && p2 < bScore) {
+ bScore = p2;
+ bPoint = 0x0D;
+ bIsBiggerSide = false;
+ } else if (aScore > bScore && p2 < aScore) {
+ aScore = p2;
+ aPoint = 0x0D;
+ aIsBiggerSide = false;
+ }
+
+ // Decide if (1,1,0,1) is closer.
+ double p3 = 3 - inSum + zins;
+ if (aScore <= bScore && p3 < bScore) {
+ bScore = p3;
+ bPoint = 0x0B;
+ bIsBiggerSide = false;
+ } else if (aScore > bScore && p3 < aScore) {
+ aScore = p3;
+ aPoint = 0x0B;
+ aIsBiggerSide = false;
+ }
+
+ // Decide if (1,1,1,0) is closer.
+ double p4 = 3 - inSum + wins;
+ if (aScore <= bScore && p4 < bScore) {
+ bScore = p4;
+ bPoint = 0x07;
+ bIsBiggerSide = false;
+ } else if (aScore > bScore && p4 < aScore) {
+ aScore = p4;
+ aPoint = 0x07;
+ aIsBiggerSide = false;
+ }
+
+ // Where each of the two closest points are determines how the extra three vertices are calculated.
+ if (aIsBiggerSide == bIsBiggerSide) {
+ if (aIsBiggerSide) { // Both closest points on the bigger side
+ byte c1 = (byte)(aPoint & bPoint);
+ byte c2 = (byte)(aPoint | bPoint);
+
+ // Two contributions are permutations of (0,0,0,1) and (0,0,0,2) based on c1
+ xsv_ext0 = xsv_ext1 = xsb;
+ ysv_ext0 = ysv_ext1 = ysb;
+ zsv_ext0 = zsv_ext1 = zsb;
+ wsv_ext0 = wsv_ext1 = wsb;
+ dx_ext0 = dx0 - SQUISH_CONSTANT_4D;
+ dy_ext0 = dy0 - SQUISH_CONSTANT_4D;
+ dz_ext0 = dz0 - SQUISH_CONSTANT_4D;
+ dw_ext0 = dw0 - SQUISH_CONSTANT_4D;
+ dx_ext1 = dx0 - 2 * SQUISH_CONSTANT_4D;
+ dy_ext1 = dy0 - 2 * SQUISH_CONSTANT_4D;
+ dz_ext1 = dz0 - 2 * SQUISH_CONSTANT_4D;
+ dw_ext1 = dw0 - 2 * SQUISH_CONSTANT_4D;
+ if ((c1 & 0x01) != 0) {
+ xsv_ext0 += 1;
+ dx_ext0 -= 1;
+ xsv_ext1 += 2;
+ dx_ext1 -= 2;
+ } else if ((c1 & 0x02) != 0) {
+ ysv_ext0 += 1;
+ dy_ext0 -= 1;
+ ysv_ext1 += 2;
+ dy_ext1 -= 2;
+ } else if ((c1 & 0x04) != 0) {
+ zsv_ext0 += 1;
+ dz_ext0 -= 1;
+ zsv_ext1 += 2;
+ dz_ext1 -= 2;
+ } else {
+ wsv_ext0 += 1;
+ dw_ext0 -= 1;
+ wsv_ext1 += 2;
+ dw_ext1 -= 2;
+ }
+
+ // One contribution is a permutation of (1,1,1,-1) based on c2
+ xsv_ext2 = xsb + 1;
+ ysv_ext2 = ysb + 1;
+ zsv_ext2 = zsb + 1;
+ wsv_ext2 = wsb + 1;
+ dx_ext2 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ dy_ext2 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ dz_ext2 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ dw_ext2 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ if ((c2 & 0x01) == 0) {
+ xsv_ext2 -= 2;
+ dx_ext2 += 2;
+ } else if ((c2 & 0x02) == 0) {
+ ysv_ext2 -= 2;
+ dy_ext2 += 2;
+ } else if ((c2 & 0x04) == 0) {
+ zsv_ext2 -= 2;
+ dz_ext2 += 2;
+ } else {
+ wsv_ext2 -= 2;
+ dw_ext2 += 2;
+ }
+ } else { // Both closest points on the smaller side
+ // One of the two extra points is (1,1,1,1)
+ xsv_ext2 = xsb + 1;
+ ysv_ext2 = ysb + 1;
+ zsv_ext2 = zsb + 1;
+ wsv_ext2 = wsb + 1;
+ dx_ext2 = dx0 - 1 - 4 * SQUISH_CONSTANT_4D;
+ dy_ext2 = dy0 - 1 - 4 * SQUISH_CONSTANT_4D;
+ dz_ext2 = dz0 - 1 - 4 * SQUISH_CONSTANT_4D;
+ dw_ext2 = dw0 - 1 - 4 * SQUISH_CONSTANT_4D;
+
+ // Other two points are based on the shared axes.
+ byte c = (byte)(aPoint & bPoint);
+
+ if ((c & 0x01) != 0) {
+ xsv_ext0 = xsb + 2;
+ xsv_ext1 = xsb + 1;
+ dx_ext0 = dx0 - 2 - 3 * SQUISH_CONSTANT_4D;
+ dx_ext1 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D;
+ } else {
+ xsv_ext0 = xsv_ext1 = xsb;
+ dx_ext0 = dx_ext1 = dx0 - 3 * SQUISH_CONSTANT_4D;
+ }
+
+ if ((c & 0x02) != 0) {
+ ysv_ext0 = ysv_ext1 = ysb + 1;
+ dy_ext0 = dy_ext1 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D;
+ if ((c & 0x01) == 0)
+ {
+ ysv_ext0 += 1;
+ dy_ext0 -= 1;
+ } else {
+ ysv_ext1 += 1;
+ dy_ext1 -= 1;
+ }
+ } else {
+ ysv_ext0 = ysv_ext1 = ysb;
+ dy_ext0 = dy_ext1 = dy0 - 3 * SQUISH_CONSTANT_4D;
+ }
+
+ if ((c & 0x04) != 0) {
+ zsv_ext0 = zsv_ext1 = zsb + 1;
+ dz_ext0 = dz_ext1 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D;
+ if ((c & 0x03) == 0)
+ {
+ zsv_ext0 += 1;
+ dz_ext0 -= 1;
+ } else {
+ zsv_ext1 += 1;
+ dz_ext1 -= 1;
+ }
+ } else {
+ zsv_ext0 = zsv_ext1 = zsb;
+ dz_ext0 = dz_ext1 = dz0 - 3 * SQUISH_CONSTANT_4D;
+ }
+
+ if ((c & 0x08) != 0)
+ {
+ wsv_ext0 = wsb + 1;
+ wsv_ext1 = wsb + 2;
+ dw_ext0 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D;
+ dw_ext1 = dw0 - 2 - 3 * SQUISH_CONSTANT_4D;
+ } else {
+ wsv_ext0 = wsv_ext1 = wsb;
+ dw_ext0 = dw_ext1 = dw0 - 3 * SQUISH_CONSTANT_4D;
+ }
+ }
+ } else { // One point on each "side"
+ byte c1, c2;
+ if (aIsBiggerSide) {
+ c1 = aPoint;
+ c2 = bPoint;
+ } else {
+ c1 = bPoint;
+ c2 = aPoint;
+ }
+
+ // Two contributions are the bigger-sided point with each 1 replaced with 2.
+ if ((c1 & 0x01) != 0) {
+ xsv_ext0 = xsb + 2;
+ xsv_ext1 = xsb + 1;
+ dx_ext0 = dx0 - 2 - 3 * SQUISH_CONSTANT_4D;
+ dx_ext1 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D;
+ } else {
+ xsv_ext0 = xsv_ext1 = xsb;
+ dx_ext0 = dx_ext1 = dx0 - 3 * SQUISH_CONSTANT_4D;
+ }
+
+ if ((c1 & 0x02) != 0) {
+ ysv_ext0 = ysv_ext1 = ysb + 1;
+ dy_ext0 = dy_ext1 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D;
+ if ((c1 & 0x01) == 0) {
+ ysv_ext0 += 1;
+ dy_ext0 -= 1;
+ } else {
+ ysv_ext1 += 1;
+ dy_ext1 -= 1;
+ }
+ } else {
+ ysv_ext0 = ysv_ext1 = ysb;
+ dy_ext0 = dy_ext1 = dy0 - 3 * SQUISH_CONSTANT_4D;
+ }
+
+ if ((c1 & 0x04) != 0) {
+ zsv_ext0 = zsv_ext1 = zsb + 1;
+ dz_ext0 = dz_ext1 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D;
+ if ((c1 & 0x03) == 0) {
+ zsv_ext0 += 1;
+ dz_ext0 -= 1;
+ } else {
+ zsv_ext1 += 1;
+ dz_ext1 -= 1;
+ }
+ } else {
+ zsv_ext0 = zsv_ext1 = zsb;
+ dz_ext0 = dz_ext1 = dz0 - 3 * SQUISH_CONSTANT_4D;
+ }
+
+ if ((c1 & 0x08) != 0) {
+ wsv_ext0 = wsb + 1;
+ wsv_ext1 = wsb + 2;
+ dw_ext0 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D;
+ dw_ext1 = dw0 - 2 - 3 * SQUISH_CONSTANT_4D;
+ } else {
+ wsv_ext0 = wsv_ext1 = wsb;
+ dw_ext0 = dw_ext1 = dw0 - 3 * SQUISH_CONSTANT_4D;
+ }
+
+ // One contribution is a permutation of (1,1,1,-1) based on the smaller-sided point
+ xsv_ext2 = xsb + 1;
+ ysv_ext2 = ysb + 1;
+ zsv_ext2 = zsb + 1;
+ wsv_ext2 = wsb + 1;
+ dx_ext2 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ dy_ext2 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ dz_ext2 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ dw_ext2 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ if ((c2 & 0x01) == 0) {
+ xsv_ext2 -= 2;
+ dx_ext2 += 2;
+ } else if ((c2 & 0x02) == 0) {
+ ysv_ext2 -= 2;
+ dy_ext2 += 2;
+ } else if ((c2 & 0x04) == 0) {
+ zsv_ext2 -= 2;
+ dz_ext2 += 2;
+ } else {
+ wsv_ext2 -= 2;
+ dw_ext2 += 2;
+ }
+ }
+
+ // Contribution (1,1,1,0)
+ double dx4 = dx0 - 1 - 3 * SQUISH_CONSTANT_4D;
+ double dy4 = dy0 - 1 - 3 * SQUISH_CONSTANT_4D;
+ double dz4 = dz0 - 1 - 3 * SQUISH_CONSTANT_4D;
+ double dw4 = dw0 - 3 * SQUISH_CONSTANT_4D;
+ double attn4 = 2 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4 - dw4 * dw4;
+ if (attn4 > 0) {
+ attn4 *= attn4;
+ value += attn4 * attn4 * extrapolate(xsb + 1, ysb + 1, zsb + 1, wsb + 0, dx4, dy4, dz4, dw4);
+ }
+
+ // Contribution (1,1,0,1)
+ double dx3 = dx4;
+ double dy3 = dy4;
+ double dz3 = dz0 - 3 * SQUISH_CONSTANT_4D;
+ double dw3 = dw0 - 1 - 3 * SQUISH_CONSTANT_4D;
+ double attn3 = 2 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3 - dw3 * dw3;
+ if (attn3 > 0) {
+ attn3 *= attn3;
+ value += attn3 * attn3 * extrapolate(xsb + 1, ysb + 1, zsb + 0, wsb + 1, dx3, dy3, dz3, dw3);
+ }
+
+ // Contribution (1,0,1,1)
+ double dx2 = dx4;
+ double dy2 = dy0 - 3 * SQUISH_CONSTANT_4D;
+ double dz2 = dz4;
+ double dw2 = dw3;
+ double attn2 = 2 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2 - dw2 * dw2;
+ if (attn2 > 0) {
+ attn2 *= attn2;
+ value += attn2 * attn2 * extrapolate(xsb + 1, ysb + 0, zsb + 1, wsb + 1, dx2, dy2, dz2, dw2);
+ }
+
+ // Contribution (0,1,1,1)
+ double dx1 = dx0 - 3 * SQUISH_CONSTANT_4D;
+ double dz1 = dz4;
+ double dy1 = dy4;
+ double dw1 = dw3;
+ double attn1 = 2 - dx1 * dx1 - dy1 * dy1 - dz1 * dz1 - dw1 * dw1;
+ if (attn1 > 0) {
+ attn1 *= attn1;
+ value += attn1 * attn1 * extrapolate(xsb + 0, ysb + 1, zsb + 1, wsb + 1, dx1, dy1, dz1, dw1);
+ }
+
+ // Contribution (1,1,0,0)
+ double dx5 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ double dy5 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ double dz5 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D;
+ double dw5 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D;
+ double attn5 = 2 - dx5 * dx5 - dy5 * dy5 - dz5 * dz5 - dw5 * dw5;
+ if (attn5 > 0) {
+ attn5 *= attn5;
+ value += attn5 * attn5 * extrapolate(xsb + 1, ysb + 1, zsb + 0, wsb + 0, dx5, dy5, dz5, dw5);
+ }
+
+ // Contribution (1,0,1,0)
+ double dx6 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ double dy6 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D;
+ double dz6 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ double dw6 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D;
+ double attn6 = 2 - dx6 * dx6 - dy6 * dy6 - dz6 * dz6 - dw6 * dw6;
+ if (attn6 > 0) {
+ attn6 *= attn6;
+ value += attn6 * attn6 * extrapolate(xsb + 1, ysb + 0, zsb + 1, wsb + 0, dx6, dy6, dz6, dw6);
+ }
+
+ // Contribution (1,0,0,1)
+ double dx7 = dx0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ double dy7 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D;
+ double dz7 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D;
+ double dw7 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ double attn7 = 2 - dx7 * dx7 - dy7 * dy7 - dz7 * dz7 - dw7 * dw7;
+ if (attn7 > 0) {
+ attn7 *= attn7;
+ value += attn7 * attn7 * extrapolate(xsb + 1, ysb + 0, zsb + 0, wsb + 1, dx7, dy7, dz7, dw7);
+ }
+
+ // Contribution (0,1,1,0)
+ double dx8 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D;
+ double dy8 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ double dz8 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ double dw8 = dw0 - 0 - 2 * SQUISH_CONSTANT_4D;
+ double attn8 = 2 - dx8 * dx8 - dy8 * dy8 - dz8 * dz8 - dw8 * dw8;
+ if (attn8 > 0) {
+ attn8 *= attn8;
+ value += attn8 * attn8 * extrapolate(xsb + 0, ysb + 1, zsb + 1, wsb + 0, dx8, dy8, dz8, dw8);
+ }
+
+ // Contribution (0,1,0,1)
+ double dx9 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D;
+ double dy9 = dy0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ double dz9 = dz0 - 0 - 2 * SQUISH_CONSTANT_4D;
+ double dw9 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ double attn9 = 2 - dx9 * dx9 - dy9 * dy9 - dz9 * dz9 - dw9 * dw9;
+ if (attn9 > 0) {
+ attn9 *= attn9;
+ value += attn9 * attn9 * extrapolate(xsb + 0, ysb + 1, zsb + 0, wsb + 1, dx9, dy9, dz9, dw9);
+ }
+
+ // Contribution (0,0,1,1)
+ double dx10 = dx0 - 0 - 2 * SQUISH_CONSTANT_4D;
+ double dy10 = dy0 - 0 - 2 * SQUISH_CONSTANT_4D;
+ double dz10 = dz0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ double dw10 = dw0 - 1 - 2 * SQUISH_CONSTANT_4D;
+ double attn10 = 2 - dx10 * dx10 - dy10 * dy10 - dz10 * dz10 - dw10 * dw10;
+ if (attn10 > 0) {
+ attn10 *= attn10;
+ value += attn10 * attn10 * extrapolate(xsb + 0, ysb + 0, zsb + 1, wsb + 1, dx10, dy10, dz10, dw10);
+ }
+ }
+
+ // First extra vertex
+ double attn_ext0 = 2 - dx_ext0 * dx_ext0 - dy_ext0 * dy_ext0 - dz_ext0 * dz_ext0 - dw_ext0 * dw_ext0;
+ if (attn_ext0 > 0)
+ {
+ attn_ext0 *= attn_ext0;
+ value += attn_ext0 * attn_ext0 * extrapolate(xsv_ext0, ysv_ext0, zsv_ext0, wsv_ext0, dx_ext0, dy_ext0, dz_ext0, dw_ext0);
+ }
+
+ // Second extra vertex
+ double attn_ext1 = 2 - dx_ext1 * dx_ext1 - dy_ext1 * dy_ext1 - dz_ext1 * dz_ext1 - dw_ext1 * dw_ext1;
+ if (attn_ext1 > 0)
+ {
+ attn_ext1 *= attn_ext1;
+ value += attn_ext1 * attn_ext1 * extrapolate(xsv_ext1, ysv_ext1, zsv_ext1, wsv_ext1, dx_ext1, dy_ext1, dz_ext1, dw_ext1);
+ }
+
+ // Third extra vertex
+ double attn_ext2 = 2 - dx_ext2 * dx_ext2 - dy_ext2 * dy_ext2 - dz_ext2 * dz_ext2 - dw_ext2 * dw_ext2;
+ if (attn_ext2 > 0)
+ {
+ attn_ext2 *= attn_ext2;
+ value += attn_ext2 * attn_ext2 * extrapolate(xsv_ext2, ysv_ext2, zsv_ext2, wsv_ext2, dx_ext2, dy_ext2, dz_ext2, dw_ext2);
+ }
+
+ return value;
+ }
+
+ private double extrapolate(int xsb, int ysb, double dx, double dy)
+ {
+ Grad2 grad = permGrad2[perm[xsb & PMASK] ^ (ysb & PMASK)];
+ return grad.dx * dx + grad.dy * dy;
+ }
+
+ private double extrapolate(int xsb, int ysb, int zsb, double dx, double dy, double dz)
+ {
+ Grad3 grad = permGrad3[perm[perm[xsb & PMASK] ^ (ysb & PMASK)] ^ (zsb & PMASK)];
+ return grad.dx * dx + grad.dy * dy + grad.dz * dz;
+ }
+
+ private double extrapolate(int xsb, int ysb, int zsb, int wsb, double dx, double dy, double dz, double dw)
+ {
+ Grad4 grad = permGrad4[perm[perm[perm[xsb & PMASK] ^ (ysb & PMASK)] ^ (zsb & PMASK)] ^ (wsb & PMASK)];
+ return grad.dx * dx + grad.dy * dy + grad.dz * dz + grad.dw * dw;
+ }
+
+ private static int fastFloor(double x) {
+ int xi = (int)x;
+ return x < xi ? xi - 1 : xi;
+ }
+
+ public static class Grad2 {
+ double dx, dy;
+ public Grad2(double dx, double dy) {
+ this.dx = dx; this.dy = dy;
+ }
+ }
+
+ public static class Grad3 {
+ double dx, dy, dz;
+ public Grad3(double dx, double dy, double dz) {
+ this.dx = dx; this.dy = dy; this.dz = dz;
+ }
+ }
+
+ public static class Grad4 {
+ double dx, dy, dz, dw;
+ public Grad4(double dx, double dy, double dz, double dw) {
+ this.dx = dx; this.dy = dy; this.dz = dz; this.dw = dw;
+ }
+ }
+
+ private static final double N2 = 7.69084574549313;
+ private static final double N3 = 26.92263139946168;
+ private static final double N4 = 8.881759591352166;
+
+ private static final Grad2[] GRADIENTS_2D = new Grad2[PSIZE];
+ private static final Grad3[] GRADIENTS_3D = new Grad3[PSIZE];
+ private static final Grad4[] GRADIENTS_4D = new Grad4[PSIZE];
+ static {
+ Grad2[] grad2 = {
+ new Grad2( 0.130526192220052, 0.99144486137381),
+ new Grad2( 0.38268343236509, 0.923879532511287),
+ new Grad2( 0.608761429008721, 0.793353340291235),
+ new Grad2( 0.793353340291235, 0.608761429008721),
+ new Grad2( 0.923879532511287, 0.38268343236509),
+ new Grad2( 0.99144486137381, 0.130526192220051),
+ new Grad2( 0.99144486137381, -0.130526192220051),
+ new Grad2( 0.923879532511287, -0.38268343236509),
+ new Grad2( 0.793353340291235, -0.60876142900872),
+ new Grad2( 0.608761429008721, -0.793353340291235),
+ new Grad2( 0.38268343236509, -0.923879532511287),
+ new Grad2( 0.130526192220052, -0.99144486137381),
+ new Grad2(-0.130526192220052, -0.99144486137381),
+ new Grad2(-0.38268343236509, -0.923879532511287),
+ new Grad2(-0.608761429008721, -0.793353340291235),
+ new Grad2(-0.793353340291235, -0.608761429008721),
+ new Grad2(-0.923879532511287, -0.38268343236509),
+ new Grad2(-0.99144486137381, -0.130526192220052),
+ new Grad2(-0.99144486137381, 0.130526192220051),
+ new Grad2(-0.923879532511287, 0.38268343236509),
+ new Grad2(-0.793353340291235, 0.608761429008721),
+ new Grad2(-0.608761429008721, 0.793353340291235),
+ new Grad2(-0.38268343236509, 0.923879532511287),
+ new Grad2(-0.130526192220052, 0.99144486137381)
+ };
+ for (int i = 0; i < grad2.length; i++) {
+ grad2[i].dx /= N2; grad2[i].dy /= N2;
+ }
+ for (int i = 0; i < PSIZE; i++) {
+ GRADIENTS_2D[i] = grad2[i % grad2.length];
+ }
+
+ Grad3[] grad3 = {
+ new Grad3(-1.4082482904633333, -1.4082482904633333, -2.6329931618533333),
+ new Grad3(-0.07491495712999985, -0.07491495712999985, -3.29965982852),
+ new Grad3( 0.24732126143473554, -1.6667938651159684, -2.838945207362466),
+ new Grad3(-1.6667938651159684, 0.24732126143473554, -2.838945207362466),
+ new Grad3(-1.4082482904633333, -2.6329931618533333, -1.4082482904633333),
+ new Grad3(-0.07491495712999985, -3.29965982852, -0.07491495712999985),
+ new Grad3(-1.6667938651159684, -2.838945207362466, 0.24732126143473554),
+ new Grad3( 0.24732126143473554, -2.838945207362466, -1.6667938651159684),
+ new Grad3( 1.5580782047233335, 0.33333333333333337, -2.8914115380566665),
+ new Grad3( 2.8914115380566665, -0.33333333333333337, -1.5580782047233335),
+ new Grad3( 1.8101897177633992, -1.2760767510338025, -2.4482280932803),
+ new Grad3( 2.4482280932803, 1.2760767510338025, -1.8101897177633992),
+ new Grad3( 1.5580782047233335, -2.8914115380566665, 0.33333333333333337),
+ new Grad3( 2.8914115380566665, -1.5580782047233335, -0.33333333333333337),
+ new Grad3( 2.4482280932803, -1.8101897177633992, 1.2760767510338025),
+ new Grad3( 1.8101897177633992, -2.4482280932803, -1.2760767510338025),
+ new Grad3(-2.6329931618533333, -1.4082482904633333, -1.4082482904633333),
+ new Grad3(-3.29965982852, -0.07491495712999985, -0.07491495712999985),
+ new Grad3(-2.838945207362466, 0.24732126143473554, -1.6667938651159684),
+ new Grad3(-2.838945207362466, -1.6667938651159684, 0.24732126143473554),
+ new Grad3( 0.33333333333333337, 1.5580782047233335, -2.8914115380566665),
+ new Grad3(-0.33333333333333337, 2.8914115380566665, -1.5580782047233335),
+ new Grad3( 1.2760767510338025, 2.4482280932803, -1.8101897177633992),
+ new Grad3(-1.2760767510338025, 1.8101897177633992, -2.4482280932803),
+ new Grad3( 0.33333333333333337, -2.8914115380566665, 1.5580782047233335),
+ new Grad3(-0.33333333333333337, -1.5580782047233335, 2.8914115380566665),
+ new Grad3(-1.2760767510338025, -2.4482280932803, 1.8101897177633992),
+ new Grad3( 1.2760767510338025, -1.8101897177633992, 2.4482280932803),
+ new Grad3( 3.29965982852, 0.07491495712999985, 0.07491495712999985),
+ new Grad3( 2.6329931618533333, 1.4082482904633333, 1.4082482904633333),
+ new Grad3( 2.838945207362466, -0.24732126143473554, 1.6667938651159684),
+ new Grad3( 2.838945207362466, 1.6667938651159684, -0.24732126143473554),
+ new Grad3(-2.8914115380566665, 1.5580782047233335, 0.33333333333333337),
+ new Grad3(-1.5580782047233335, 2.8914115380566665, -0.33333333333333337),
+ new Grad3(-2.4482280932803, 1.8101897177633992, -1.2760767510338025),
+ new Grad3(-1.8101897177633992, 2.4482280932803, 1.2760767510338025),
+ new Grad3(-2.8914115380566665, 0.33333333333333337, 1.5580782047233335),
+ new Grad3(-1.5580782047233335, -0.33333333333333337, 2.8914115380566665),
+ new Grad3(-1.8101897177633992, 1.2760767510338025, 2.4482280932803),
+ new Grad3(-2.4482280932803, -1.2760767510338025, 1.8101897177633992),
+ new Grad3( 0.07491495712999985, 3.29965982852, 0.07491495712999985),
+ new Grad3( 1.4082482904633333, 2.6329931618533333, 1.4082482904633333),
+ new Grad3( 1.6667938651159684, 2.838945207362466, -0.24732126143473554),
+ new Grad3(-0.24732126143473554, 2.838945207362466, 1.6667938651159684),
+ new Grad3( 0.07491495712999985, 0.07491495712999985, 3.29965982852),
+ new Grad3( 1.4082482904633333, 1.4082482904633333, 2.6329931618533333),
+ new Grad3(-0.24732126143473554, 1.6667938651159684, 2.838945207362466),
+ new Grad3( 1.6667938651159684, -0.24732126143473554, 2.838945207362466)
+ };
+ for (int i = 0; i < grad3.length; i++) {
+ grad3[i].dx /= N3; grad3[i].dy /= N3; grad3[i].dz /= N3;
+ }
+ for (int i = 0; i < PSIZE; i++) {
+ GRADIENTS_3D[i] = grad3[i % grad3.length];
+ }
+
+ Grad4[] grad4 = {
+ new Grad4(-0.753341017856078, -0.37968289875261624, -0.37968289875261624, -0.37968289875261624),
+ new Grad4(-0.7821684431180708, -0.4321472685365301, -0.4321472685365301, 0.12128480194602098),
+ new Grad4(-0.7821684431180708, -0.4321472685365301, 0.12128480194602098, -0.4321472685365301),
+ new Grad4(-0.7821684431180708, 0.12128480194602098, -0.4321472685365301, -0.4321472685365301),
+ new Grad4(-0.8586508742123365, -0.508629699630796, 0.044802370851755174, 0.044802370851755174),
+ new Grad4(-0.8586508742123365, 0.044802370851755174, -0.508629699630796, 0.044802370851755174),
+ new Grad4(-0.8586508742123365, 0.044802370851755174, 0.044802370851755174, -0.508629699630796),
+ new Grad4(-0.9982828964265062, -0.03381941603233842, -0.03381941603233842, -0.03381941603233842),
+ new Grad4(-0.37968289875261624, -0.753341017856078, -0.37968289875261624, -0.37968289875261624),
+ new Grad4(-0.4321472685365301, -0.7821684431180708, -0.4321472685365301, 0.12128480194602098),
+ new Grad4(-0.4321472685365301, -0.7821684431180708, 0.12128480194602098, -0.4321472685365301),
+ new Grad4( 0.12128480194602098, -0.7821684431180708, -0.4321472685365301, -0.4321472685365301),
+ new Grad4(-0.508629699630796, -0.8586508742123365, 0.044802370851755174, 0.044802370851755174),
+ new Grad4( 0.044802370851755174, -0.8586508742123365, -0.508629699630796, 0.044802370851755174),
+ new Grad4( 0.044802370851755174, -0.8586508742123365, 0.044802370851755174, -0.508629699630796),
+ new Grad4(-0.03381941603233842, -0.9982828964265062, -0.03381941603233842, -0.03381941603233842),
+ new Grad4(-0.37968289875261624, -0.37968289875261624, -0.753341017856078, -0.37968289875261624),
+ new Grad4(-0.4321472685365301, -0.4321472685365301, -0.7821684431180708, 0.12128480194602098),
+ new Grad4(-0.4321472685365301, 0.12128480194602098, -0.7821684431180708, -0.4321472685365301),
+ new Grad4( 0.12128480194602098, -0.4321472685365301, -0.7821684431180708, -0.4321472685365301),
+ new Grad4(-0.508629699630796, 0.044802370851755174, -0.8586508742123365, 0.044802370851755174),
+ new Grad4( 0.044802370851755174, -0.508629699630796, -0.8586508742123365, 0.044802370851755174),
+ new Grad4( 0.044802370851755174, 0.044802370851755174, -0.8586508742123365, -0.508629699630796),
+ new Grad4(-0.03381941603233842, -0.03381941603233842, -0.9982828964265062, -0.03381941603233842),
+ new Grad4(-0.37968289875261624, -0.37968289875261624, -0.37968289875261624, -0.753341017856078),
+ new Grad4(-0.4321472685365301, -0.4321472685365301, 0.12128480194602098, -0.7821684431180708),
+ new Grad4(-0.4321472685365301, 0.12128480194602098, -0.4321472685365301, -0.7821684431180708),
+ new Grad4( 0.12128480194602098, -0.4321472685365301, -0.4321472685365301, -0.7821684431180708),
+ new Grad4(-0.508629699630796, 0.044802370851755174, 0.044802370851755174, -0.8586508742123365),
+ new Grad4( 0.044802370851755174, -0.508629699630796, 0.044802370851755174, -0.8586508742123365),
+ new Grad4( 0.044802370851755174, 0.044802370851755174, -0.508629699630796, -0.8586508742123365),
+ new Grad4(-0.03381941603233842, -0.03381941603233842, -0.03381941603233842, -0.9982828964265062),
+ new Grad4(-0.6740059517812944, -0.3239847771997537, -0.3239847771997537, 0.5794684678643381),
+ new Grad4(-0.7504883828755602, -0.4004672082940195, 0.15296486218853164, 0.5029860367700724),
+ new Grad4(-0.7504883828755602, 0.15296486218853164, -0.4004672082940195, 0.5029860367700724),
+ new Grad4(-0.8828161875373585, 0.08164729285680945, 0.08164729285680945, 0.4553054119602712),
+ new Grad4(-0.4553054119602712, -0.08164729285680945, -0.08164729285680945, 0.8828161875373585),
+ new Grad4(-0.5029860367700724, -0.15296486218853164, 0.4004672082940195, 0.7504883828755602),
+ new Grad4(-0.5029860367700724, 0.4004672082940195, -0.15296486218853164, 0.7504883828755602),
+ new Grad4(-0.5794684678643381, 0.3239847771997537, 0.3239847771997537, 0.6740059517812944),
+ new Grad4(-0.3239847771997537, -0.6740059517812944, -0.3239847771997537, 0.5794684678643381),
+ new Grad4(-0.4004672082940195, -0.7504883828755602, 0.15296486218853164, 0.5029860367700724),
+ new Grad4( 0.15296486218853164, -0.7504883828755602, -0.4004672082940195, 0.5029860367700724),
+ new Grad4( 0.08164729285680945, -0.8828161875373585, 0.08164729285680945, 0.4553054119602712),
+ new Grad4(-0.08164729285680945, -0.4553054119602712, -0.08164729285680945, 0.8828161875373585),
+ new Grad4(-0.15296486218853164, -0.5029860367700724, 0.4004672082940195, 0.7504883828755602),
+ new Grad4( 0.4004672082940195, -0.5029860367700724, -0.15296486218853164, 0.7504883828755602),
+ new Grad4( 0.3239847771997537, -0.5794684678643381, 0.3239847771997537, 0.6740059517812944),
+ new Grad4(-0.3239847771997537, -0.3239847771997537, -0.6740059517812944, 0.5794684678643381),
+ new Grad4(-0.4004672082940195, 0.15296486218853164, -0.7504883828755602, 0.5029860367700724),
+ new Grad4( 0.15296486218853164, -0.4004672082940195, -0.7504883828755602, 0.5029860367700724),
+ new Grad4( 0.08164729285680945, 0.08164729285680945, -0.8828161875373585, 0.4553054119602712),
+ new Grad4(-0.08164729285680945, -0.08164729285680945, -0.4553054119602712, 0.8828161875373585),
+ new Grad4(-0.15296486218853164, 0.4004672082940195, -0.5029860367700724, 0.7504883828755602),
+ new Grad4( 0.4004672082940195, -0.15296486218853164, -0.5029860367700724, 0.7504883828755602),
+ new Grad4( 0.3239847771997537, 0.3239847771997537, -0.5794684678643381, 0.6740059517812944),
+ new Grad4(-0.6740059517812944, -0.3239847771997537, 0.5794684678643381, -0.3239847771997537),
+ new Grad4(-0.7504883828755602, -0.4004672082940195, 0.5029860367700724, 0.15296486218853164),
+ new Grad4(-0.7504883828755602, 0.15296486218853164, 0.5029860367700724, -0.4004672082940195),
+ new Grad4(-0.8828161875373585, 0.08164729285680945, 0.4553054119602712, 0.08164729285680945),
+ new Grad4(-0.4553054119602712, -0.08164729285680945, 0.8828161875373585, -0.08164729285680945),
+ new Grad4(-0.5029860367700724, -0.15296486218853164, 0.7504883828755602, 0.4004672082940195),
+ new Grad4(-0.5029860367700724, 0.4004672082940195, 0.7504883828755602, -0.15296486218853164),
+ new Grad4(-0.5794684678643381, 0.3239847771997537, 0.6740059517812944, 0.3239847771997537),
+ new Grad4(-0.3239847771997537, -0.6740059517812944, 0.5794684678643381, -0.3239847771997537),
+ new Grad4(-0.4004672082940195, -0.7504883828755602, 0.5029860367700724, 0.15296486218853164),
+ new Grad4( 0.15296486218853164, -0.7504883828755602, 0.5029860367700724, -0.4004672082940195),
+ new Grad4( 0.08164729285680945, -0.8828161875373585, 0.4553054119602712, 0.08164729285680945),
+ new Grad4(-0.08164729285680945, -0.4553054119602712, 0.8828161875373585, -0.08164729285680945),
+ new Grad4(-0.15296486218853164, -0.5029860367700724, 0.7504883828755602, 0.4004672082940195),
+ new Grad4( 0.4004672082940195, -0.5029860367700724, 0.7504883828755602, -0.15296486218853164),
+ new Grad4( 0.3239847771997537, -0.5794684678643381, 0.6740059517812944, 0.3239847771997537),
+ new Grad4(-0.3239847771997537, -0.3239847771997537, 0.5794684678643381, -0.6740059517812944),
+ new Grad4(-0.4004672082940195, 0.15296486218853164, 0.5029860367700724, -0.7504883828755602),
+ new Grad4( 0.15296486218853164, -0.4004672082940195, 0.5029860367700724, -0.7504883828755602),
+ new Grad4( 0.08164729285680945, 0.08164729285680945, 0.4553054119602712, -0.8828161875373585),
+ new Grad4(-0.08164729285680945, -0.08164729285680945, 0.8828161875373585, -0.4553054119602712),
+ new Grad4(-0.15296486218853164, 0.4004672082940195, 0.7504883828755602, -0.5029860367700724),
+ new Grad4( 0.4004672082940195, -0.15296486218853164, 0.7504883828755602, -0.5029860367700724),
+ new Grad4( 0.3239847771997537, 0.3239847771997537, 0.6740059517812944, -0.5794684678643381),
+ new Grad4(-0.6740059517812944, 0.5794684678643381, -0.3239847771997537, -0.3239847771997537),
+ new Grad4(-0.7504883828755602, 0.5029860367700724, -0.4004672082940195, 0.15296486218853164),
+ new Grad4(-0.7504883828755602, 0.5029860367700724, 0.15296486218853164, -0.4004672082940195),
+ new Grad4(-0.8828161875373585, 0.4553054119602712, 0.08164729285680945, 0.08164729285680945),
+ new Grad4(-0.4553054119602712, 0.8828161875373585, -0.08164729285680945, -0.08164729285680945),
+ new Grad4(-0.5029860367700724, 0.7504883828755602, -0.15296486218853164, 0.4004672082940195),
+ new Grad4(-0.5029860367700724, 0.7504883828755602, 0.4004672082940195, -0.15296486218853164),
+ new Grad4(-0.5794684678643381, 0.6740059517812944, 0.3239847771997537, 0.3239847771997537),
+ new Grad4(-0.3239847771997537, 0.5794684678643381, -0.6740059517812944, -0.3239847771997537),
+ new Grad4(-0.4004672082940195, 0.5029860367700724, -0.7504883828755602, 0.15296486218853164),
+ new Grad4( 0.15296486218853164, 0.5029860367700724, -0.7504883828755602, -0.4004672082940195),
+ new Grad4( 0.08164729285680945, 0.4553054119602712, -0.8828161875373585, 0.08164729285680945),
+ new Grad4(-0.08164729285680945, 0.8828161875373585, -0.4553054119602712, -0.08164729285680945),
+ new Grad4(-0.15296486218853164, 0.7504883828755602, -0.5029860367700724, 0.4004672082940195),
+ new Grad4( 0.4004672082940195, 0.7504883828755602, -0.5029860367700724, -0.15296486218853164),
+ new Grad4( 0.3239847771997537, 0.6740059517812944, -0.5794684678643381, 0.3239847771997537),
+ new Grad4(-0.3239847771997537, 0.5794684678643381, -0.3239847771997537, -0.6740059517812944),
+ new Grad4(-0.4004672082940195, 0.5029860367700724, 0.15296486218853164, -0.7504883828755602),
+ new Grad4( 0.15296486218853164, 0.5029860367700724, -0.4004672082940195, -0.7504883828755602),
+ new Grad4( 0.08164729285680945, 0.4553054119602712, 0.08164729285680945, -0.8828161875373585),
+ new Grad4(-0.08164729285680945, 0.8828161875373585, -0.08164729285680945, -0.4553054119602712),
+ new Grad4(-0.15296486218853164, 0.7504883828755602, 0.4004672082940195, -0.5029860367700724),
+ new Grad4( 0.4004672082940195, 0.7504883828755602, -0.15296486218853164, -0.5029860367700724),
+ new Grad4( 0.3239847771997537, 0.6740059517812944, 0.3239847771997537, -0.5794684678643381),
+ new Grad4( 0.5794684678643381, -0.6740059517812944, -0.3239847771997537, -0.3239847771997537),
+ new Grad4( 0.5029860367700724, -0.7504883828755602, -0.4004672082940195, 0.15296486218853164),
+ new Grad4( 0.5029860367700724, -0.7504883828755602, 0.15296486218853164, -0.4004672082940195),
+ new Grad4( 0.4553054119602712, -0.8828161875373585, 0.08164729285680945, 0.08164729285680945),
+ new Grad4( 0.8828161875373585, -0.4553054119602712, -0.08164729285680945, -0.08164729285680945),
+ new Grad4( 0.7504883828755602, -0.5029860367700724, -0.15296486218853164, 0.4004672082940195),
+ new Grad4( 0.7504883828755602, -0.5029860367700724, 0.4004672082940195, -0.15296486218853164),
+ new Grad4( 0.6740059517812944, -0.5794684678643381, 0.3239847771997537, 0.3239847771997537),
+ new Grad4( 0.5794684678643381, -0.3239847771997537, -0.6740059517812944, -0.3239847771997537),
+ new Grad4( 0.5029860367700724, -0.4004672082940195, -0.7504883828755602, 0.15296486218853164),
+ new Grad4( 0.5029860367700724, 0.15296486218853164, -0.7504883828755602, -0.4004672082940195),
+ new Grad4( 0.4553054119602712, 0.08164729285680945, -0.8828161875373585, 0.08164729285680945),
+ new Grad4( 0.8828161875373585, -0.08164729285680945, -0.4553054119602712, -0.08164729285680945),
+ new Grad4( 0.7504883828755602, -0.15296486218853164, -0.5029860367700724, 0.4004672082940195),
+ new Grad4( 0.7504883828755602, 0.4004672082940195, -0.5029860367700724, -0.15296486218853164),
+ new Grad4( 0.6740059517812944, 0.3239847771997537, -0.5794684678643381, 0.3239847771997537),
+ new Grad4( 0.5794684678643381, -0.3239847771997537, -0.3239847771997537, -0.6740059517812944),
+ new Grad4( 0.5029860367700724, -0.4004672082940195, 0.15296486218853164, -0.7504883828755602),
+ new Grad4( 0.5029860367700724, 0.15296486218853164, -0.4004672082940195, -0.7504883828755602),
+ new Grad4( 0.4553054119602712, 0.08164729285680945, 0.08164729285680945, -0.8828161875373585),
+ new Grad4( 0.8828161875373585, -0.08164729285680945, -0.08164729285680945, -0.4553054119602712),
+ new Grad4( 0.7504883828755602, -0.15296486218853164, 0.4004672082940195, -0.5029860367700724),
+ new Grad4( 0.7504883828755602, 0.4004672082940195, -0.15296486218853164, -0.5029860367700724),
+ new Grad4( 0.6740059517812944, 0.3239847771997537, 0.3239847771997537, -0.5794684678643381),
+ new Grad4( 0.03381941603233842, 0.03381941603233842, 0.03381941603233842, 0.9982828964265062),
+ new Grad4(-0.044802370851755174, -0.044802370851755174, 0.508629699630796, 0.8586508742123365),
+ new Grad4(-0.044802370851755174, 0.508629699630796, -0.044802370851755174, 0.8586508742123365),
+ new Grad4(-0.12128480194602098, 0.4321472685365301, 0.4321472685365301, 0.7821684431180708),
+ new Grad4( 0.508629699630796, -0.044802370851755174, -0.044802370851755174, 0.8586508742123365),
+ new Grad4( 0.4321472685365301, -0.12128480194602098, 0.4321472685365301, 0.7821684431180708),
+ new Grad4( 0.4321472685365301, 0.4321472685365301, -0.12128480194602098, 0.7821684431180708),
+ new Grad4( 0.37968289875261624, 0.37968289875261624, 0.37968289875261624, 0.753341017856078),
+ new Grad4( 0.03381941603233842, 0.03381941603233842, 0.9982828964265062, 0.03381941603233842),
+ new Grad4(-0.044802370851755174, 0.044802370851755174, 0.8586508742123365, 0.508629699630796),
+ new Grad4(-0.044802370851755174, 0.508629699630796, 0.8586508742123365, -0.044802370851755174),
+ new Grad4(-0.12128480194602098, 0.4321472685365301, 0.7821684431180708, 0.4321472685365301),
+ new Grad4( 0.508629699630796, -0.044802370851755174, 0.8586508742123365, -0.044802370851755174),
+ new Grad4( 0.4321472685365301, -0.12128480194602098, 0.7821684431180708, 0.4321472685365301),
+ new Grad4( 0.4321472685365301, 0.4321472685365301, 0.7821684431180708, -0.12128480194602098),
+ new Grad4( 0.37968289875261624, 0.37968289875261624, 0.753341017856078, 0.37968289875261624),
+ new Grad4( 0.03381941603233842, 0.9982828964265062, 0.03381941603233842, 0.03381941603233842),
+ new Grad4(-0.044802370851755174, 0.8586508742123365, -0.044802370851755174, 0.508629699630796),
+ new Grad4(-0.044802370851755174, 0.8586508742123365, 0.508629699630796, -0.044802370851755174),
+ new Grad4(-0.12128480194602098, 0.7821684431180708, 0.4321472685365301, 0.4321472685365301),
+ new Grad4( 0.508629699630796, 0.8586508742123365, -0.044802370851755174, -0.044802370851755174),
+ new Grad4( 0.4321472685365301, 0.7821684431180708, -0.12128480194602098, 0.4321472685365301),
+ new Grad4( 0.4321472685365301, 0.7821684431180708, 0.4321472685365301, -0.12128480194602098),
+ new Grad4( 0.37968289875261624, 0.753341017856078, 0.37968289875261624, 0.37968289875261624),
+ new Grad4( 0.9982828964265062, 0.03381941603233842, 0.03381941603233842, 0.03381941603233842),
+ new Grad4( 0.8586508742123365, -0.044802370851755174, -0.044802370851755174, 0.508629699630796),
+ new Grad4( 0.8586508742123365, -0.044802370851755174, 0.508629699630796, -0.044802370851755174),
+ new Grad4( 0.7821684431180708, -0.12128480194602098, 0.4321472685365301, 0.4321472685365301),
+ new Grad4( 0.8586508742123365, 0.508629699630796, -0.044802370851755174, -0.044802370851755174),
+ new Grad4( 0.7821684431180708, 0.4321472685365301, -0.12128480194602098, 0.4321472685365301),
+ new Grad4( 0.7821684431180708, 0.4321472685365301, 0.4321472685365301, -0.12128480194602098),
+ new Grad4( 0.753341017856078, 0.37968289875261624, 0.37968289875261624, 0.37968289875261624)
+ };
+ for (int i = 0; i < grad4.length; i++) {
+ grad4[i].dx /= N4; grad4[i].dy /= N4; grad4[i].dz /= N4; grad4[i].dw /= N4;
+ }
+ for (int i = 0; i < PSIZE; i++) {
+ GRADIENTS_4D[i] = grad4[i % grad4.length];
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/forge-adventure/src/main/java/forge/adventure/world/World.java b/forge-adventure/src/main/java/forge/adventure/world/World.java
new file mode 100644
index 00000000000..37d8ce5c90e
--- /dev/null
+++ b/forge-adventure/src/main/java/forge/adventure/world/World.java
@@ -0,0 +1,97 @@
+package forge.adventure.world;
+
+import com.badlogic.gdx.files.FileHandle;
+import com.badlogic.gdx.graphics.Pixmap;
+import com.badlogic.gdx.utils.Json;
+import forge.adventure.data.BiomData;
+import forge.adventure.data.WorldData;
+
+import java.awt.image.BufferedImage;
+import java.util.Random;
+
+public class World {
+
+
+ public Pixmap GenerateNew() {
+
+ FileHandle handle= forge.adventure.util.Res.CurrentRes.GetFile("world/word.json");
+ String rawJson=handle.readString();
+ WorldData data = (new Json()).fromJson(WorldData.class,rawJson);
+ int seed= new Random().nextInt();
+ OpenSimplexNoise noise=new OpenSimplexNoise(seed);
+
+ double noiceZoom=10;
+
+ //save at all data
+ double[][] noiseData=new double[data.sizeX][data.sizeY];
+
+ for(int x=0;x