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