// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.procedurallib.logic;

import javax.annotation.Nonnull;
import com.hypixel.hytale.procedurallib.NoiseFunction;

public class OldSimplexNoise implements NoiseFunction
{
    public static final OldSimplexNoise INSTANCE;
    private static final double STRETCH_CONSTANT_2D = -0.211324865405187;
    private static final double SQUISH_CONSTANT_2D = 0.366025403784439;
    private static final double STRETCH_CONSTANT_3D = -0.16666666666666666;
    private static final double SQUISH_CONSTANT_3D = 0.3333333333333333;
    private static final double NORM_CONSTANT_2D = 47.0;
    private static final double NORM_CONSTANT_3D = 103.0;
    @Nonnull
    private static DoubleArray.Double2[] gradients2D;
    @Nonnull
    private static DoubleArray.Double3[] gradients3D;
    
    private OldSimplexNoise() {
    }
    
    @Override
    public double get(final int seed, final int offsetSeed, final double x, final double y) {
        final double stretchOffset = (x + y) * -0.211324865405187;
        final double xs = x + stretchOffset;
        final double ys = y + stretchOffset;
        int xsb = fastFloor(xs);
        int ysb = fastFloor(ys);
        final double squishOffset = (xsb + ysb) * 0.366025403784439;
        final double xb = xsb + squishOffset;
        final double yb = ysb + squishOffset;
        final double xins = xs - xsb;
        final double yins = ys - ysb;
        final double inSum = xins + yins;
        double dx0 = x - xb;
        double dy0 = y - yb;
        double value = 0.0;
        final double dx2 = dx0 - 1.0 - 0.366025403784439;
        final double dy2 = dy0 - 0.0 - 0.366025403784439;
        double attn1 = 2.0 - dx2 * dx2 - dy2 * dy2;
        if (attn1 > 0.0) {
            attn1 *= attn1;
            value += attn1 * attn1 * extrapolate(offsetSeed, xsb + 1, ysb + 0, dx2, dy2);
        }
        final double dx3 = dx0 - 0.0 - 0.366025403784439;
        final double dy3 = dy0 - 1.0 - 0.366025403784439;
        double attn2 = 2.0 - dx3 * dx3 - dy3 * dy3;
        if (attn2 > 0.0) {
            attn2 *= attn2;
            value += attn2 * attn2 * extrapolate(offsetSeed, xsb + 0, ysb + 1, dx3, dy3);
        }
        int xsv_ext;
        int ysv_ext;
        double dx_ext;
        double dy_ext;
        if (inSum <= 1.0) {
            final double zins = 1.0 - inSum;
            if (zins > xins || zins > yins) {
                if (xins > yins) {
                    xsv_ext = xsb + 1;
                    ysv_ext = ysb - 1;
                    dx_ext = dx0 - 1.0;
                    dy_ext = dy0 + 1.0;
                }
                else {
                    xsv_ext = xsb - 1;
                    ysv_ext = ysb + 1;
                    dx_ext = dx0 + 1.0;
                    dy_ext = dy0 - 1.0;
                }
            }
            else {
                xsv_ext = xsb + 1;
                ysv_ext = ysb + 1;
                dx_ext = dx0 - 1.0 - 0.732050807568878;
                dy_ext = dy0 - 1.0 - 0.732050807568878;
            }
        }
        else {
            final double zins = 2.0 - inSum;
            if (zins < xins || zins < yins) {
                if (xins > yins) {
                    xsv_ext = xsb + 2;
                    ysv_ext = ysb + 0;
                    dx_ext = dx0 - 2.0 - 0.732050807568878;
                    dy_ext = dy0 + 0.0 - 0.732050807568878;
                }
                else {
                    xsv_ext = xsb + 0;
                    ysv_ext = ysb + 2;
                    dx_ext = dx0 + 0.0 - 0.732050807568878;
                    dy_ext = dy0 - 2.0 - 0.732050807568878;
                }
            }
            else {
                dx_ext = dx0;
                dy_ext = dy0;
                xsv_ext = xsb;
                ysv_ext = ysb;
            }
            ++xsb;
            ++ysb;
            dx0 = dx0 - 1.0 - 0.732050807568878;
            dy0 = dy0 - 1.0 - 0.732050807568878;
        }
        double attn3 = 2.0 - dx0 * dx0 - dy0 * dy0;
        if (attn3 > 0.0) {
            attn3 *= attn3;
            value += attn3 * attn3 * extrapolate(offsetSeed, xsb, ysb, dx0, dy0);
        }
        double attn_ext = 2.0 - dx_ext * dx_ext - dy_ext * dy_ext;
        if (attn_ext > 0.0) {
            attn_ext *= attn_ext;
            value += attn_ext * attn_ext * extrapolate(offsetSeed, xsv_ext, ysv_ext, dx_ext, dy_ext);
        }
        return value / 47.0;
    }
    
    @Override
    public double get(final int seed, final int offsetSeed, final double x, final double y, final double z) {
        final double stretchOffset = (x + y + z) * -0.16666666666666666;
        final double xs = x + stretchOffset;
        final double ys = y + stretchOffset;
        final double zs = z + stretchOffset;
        final int xsb = fastFloor(xs);
        final int ysb = fastFloor(ys);
        final int zsb = fastFloor(zs);
        final double squishOffset = (xsb + ysb + zsb) * 0.3333333333333333;
        final double xb = xsb + squishOffset;
        final double yb = ysb + squishOffset;
        final double zb = zsb + squishOffset;
        final double xins = xs - xsb;
        final double yins = ys - ysb;
        final double zins = zs - zsb;
        final double inSum = xins + yins + zins;
        double dx0 = x - xb;
        double dy0 = y - yb;
        double dz0 = z - zb;
        double value = 0.0;
        int xsv_ext0;
        int xsv_ext2;
        double dx_ext0;
        double dx_ext2;
        int ysv_ext2;
        int ysv_ext1;
        double dy_ext2;
        double dy_ext1;
        int zsv_ext0;
        int zsv_ext2;
        double dz_ext0;
        double dz_ext2;
        if (inSum <= 1.0) {
            byte aPoint = 1;
            double aScore = xins;
            byte bPoint = 2;
            double bScore = yins;
            if (aScore >= bScore && zins > bScore) {
                bScore = zins;
                bPoint = 4;
            }
            else if (aScore < bScore && zins > aScore) {
                aScore = zins;
                aPoint = 4;
            }
            final double wins = 1.0 - inSum;
            if (wins > aScore || wins > bScore) {
                final byte c = (bScore > aScore) ? bPoint : aPoint;
                if ((c & 0x1) == 0x0) {
                    xsv_ext0 = xsb - 1;
                    xsv_ext2 = xsb;
                    dx_ext0 = dx0 + 1.0;
                    dx_ext2 = dx0;
                }
                else {
                    xsv_ext2 = (xsv_ext0 = xsb + 1);
                    dx_ext2 = (dx_ext0 = dx0 - 1.0);
                }
                if ((c & 0x2) == 0x0) {
                    ysv_ext1 = (ysv_ext2 = ysb);
                    dy_ext1 = (dy_ext2 = dy0);
                    if ((c & 0x1) == 0x0) {
                        --ysv_ext1;
                        ++dy_ext1;
                    }
                    else {
                        --ysv_ext2;
                        ++dy_ext2;
                    }
                }
                else {
                    ysv_ext1 = (ysv_ext2 = ysb + 1);
                    dy_ext1 = (dy_ext2 = dy0 - 1.0);
                }
                if ((c & 0x4) == 0x0) {
                    zsv_ext0 = zsb;
                    zsv_ext2 = zsb - 1;
                    dz_ext0 = dz0;
                    dz_ext2 = dz0 + 1.0;
                }
                else {
                    zsv_ext2 = (zsv_ext0 = zsb + 1);
                    dz_ext2 = (dz_ext0 = dz0 - 1.0);
                }
            }
            else {
                final byte c = (byte)(aPoint | bPoint);
                if ((c & 0x1) == 0x0) {
                    xsv_ext0 = xsb;
                    xsv_ext2 = xsb - 1;
                    dx_ext0 = dx0 - 0.6666666666666666;
                    dx_ext2 = dx0 + 1.0 - 0.3333333333333333;
                }
                else {
                    xsv_ext2 = (xsv_ext0 = xsb + 1);
                    dx_ext0 = dx0 - 1.0 - 0.6666666666666666;
                    dx_ext2 = dx0 - 1.0 - 0.3333333333333333;
                }
                if ((c & 0x2) == 0x0) {
                    ysv_ext2 = ysb;
                    ysv_ext1 = ysb - 1;
                    dy_ext2 = dy0 - 0.6666666666666666;
                    dy_ext1 = dy0 + 1.0 - 0.3333333333333333;
                }
                else {
                    ysv_ext1 = (ysv_ext2 = ysb + 1);
                    dy_ext2 = dy0 - 1.0 - 0.6666666666666666;
                    dy_ext1 = dy0 - 1.0 - 0.3333333333333333;
                }
                if ((c & 0x4) == 0x0) {
                    zsv_ext0 = zsb;
                    zsv_ext2 = zsb - 1;
                    dz_ext0 = dz0 - 0.6666666666666666;
                    dz_ext2 = dz0 + 1.0 - 0.3333333333333333;
                }
                else {
                    zsv_ext2 = (zsv_ext0 = zsb + 1);
                    dz_ext0 = dz0 - 1.0 - 0.6666666666666666;
                    dz_ext2 = dz0 - 1.0 - 0.3333333333333333;
                }
            }
            double attn0 = 2.0 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0;
            if (attn0 > 0.0) {
                attn0 *= attn0;
                value += attn0 * attn0 * extrapolate(offsetSeed, xsb + 0, ysb + 0, zsb + 0, dx0, dy0, dz0);
            }
            final double dx2 = dx0 - 1.0 - 0.3333333333333333;
            final double dy2 = dy0 - 0.0 - 0.3333333333333333;
            final double dz2 = dz0 - 0.0 - 0.3333333333333333;
            double attn2 = 2.0 - dx2 * dx2 - dy2 * dy2 - dz2 * dz2;
            if (attn2 > 0.0) {
                attn2 *= attn2;
                value += attn2 * attn2 * extrapolate(offsetSeed, xsb + 1, ysb + 0, zsb + 0, dx2, dy2, dz2);
            }
            final double dx3 = dx0 - 0.0 - 0.3333333333333333;
            final double dy3 = dy0 - 1.0 - 0.3333333333333333;
            final double dz3 = dz2;
            double attn3 = 2.0 - dx3 * dx3 - dy3 * dy3 - dz3 * dz3;
            if (attn3 > 0.0) {
                attn3 *= attn3;
                value += attn3 * attn3 * extrapolate(offsetSeed, xsb + 0, ysb + 1, zsb + 0, dx3, dy3, dz3);
            }
            final double dx4 = dx3;
            final double dy4 = dy2;
            final double dz4 = dz0 - 1.0 - 0.3333333333333333;
            double attn4 = 2.0 - dx4 * dx4 - dy4 * dy4 - dz4 * dz4;
            if (attn4 > 0.0) {
                attn4 *= attn4;
                value += attn4 * attn4 * extrapolate(offsetSeed, xsb + 0, ysb + 0, zsb + 1, dx4, dy4, dz4);
            }
        }
        else if (inSum >= 2.0) {
            byte aPoint = 6;
            double aScore = xins;
            byte bPoint = 5;
            double bScore = yins;
            if (aScore <= bScore && zins < bScore) {
                bScore = zins;
                bPoint = 3;
            }
            else if (aScore > bScore && zins < aScore) {
                aScore = zins;
                aPoint = 3;
            }
            final double wins = 3.0 - inSum;
            if (wins < aScore || wins < bScore) {
                final byte c = (bScore < aScore) ? bPoint : aPoint;
                if ((c & 0x1) != 0x0) {
                    xsv_ext0 = xsb + 2;
                    xsv_ext2 = xsb + 1;
                    dx_ext0 = dx0 - 2.0 - 1.0;
                    dx_ext2 = dx0 - 1.0 - 1.0;
                }
                else {
                    xsv_ext2 = (xsv_ext0 = xsb);
                    dx_ext2 = (dx_ext0 = dx0 - 1.0);
                }
                if ((c & 0x2) != 0x0) {
                    ysv_ext1 = (ysv_ext2 = ysb + 1);
                    dy_ext1 = (dy_ext2 = dy0 - 1.0 - 1.0);
                    if ((c & 0x1) != 0x0) {
                        ++ysv_ext1;
                        --dy_ext1;
                    }
                    else {
                        ++ysv_ext2;
                        --dy_ext2;
                    }
                }
                else {
                    ysv_ext1 = (ysv_ext2 = ysb);
                    dy_ext1 = (dy_ext2 = dy0 - 1.0);
                }
                if ((c & 0x4) != 0x0) {
                    zsv_ext0 = zsb + 1;
                    zsv_ext2 = zsb + 2;
                    dz_ext0 = dz0 - 1.0 - 1.0;
                    dz_ext2 = dz0 - 2.0 - 1.0;
                }
                else {
                    zsv_ext2 = (zsv_ext0 = zsb);
                    dz_ext2 = (dz_ext0 = dz0 - 1.0);
                }
            }
            else {
                final byte c = (byte)(aPoint & bPoint);
                if ((c & 0x1) != 0x0) {
                    xsv_ext0 = xsb + 1;
                    xsv_ext2 = xsb + 2;
                    dx_ext0 = dx0 - 1.0 - 0.3333333333333333;
                    dx_ext2 = dx0 - 2.0 - 0.6666666666666666;
                }
                else {
                    xsv_ext2 = (xsv_ext0 = xsb);
                    dx_ext0 = dx0 - 0.3333333333333333;
                    dx_ext2 = dx0 - 0.6666666666666666;
                }
                if ((c & 0x2) != 0x0) {
                    ysv_ext2 = ysb + 1;
                    ysv_ext1 = ysb + 2;
                    dy_ext2 = dy0 - 1.0 - 0.3333333333333333;
                    dy_ext1 = dy0 - 2.0 - 0.6666666666666666;
                }
                else {
                    ysv_ext1 = (ysv_ext2 = ysb);
                    dy_ext2 = dy0 - 0.3333333333333333;
                    dy_ext1 = dy0 - 0.6666666666666666;
                }
                if ((c & 0x4) != 0x0) {
                    zsv_ext0 = zsb + 1;
                    zsv_ext2 = zsb + 2;
                    dz_ext0 = dz0 - 1.0 - 0.3333333333333333;
                    dz_ext2 = dz0 - 2.0 - 0.6666666666666666;
                }
                else {
                    zsv_ext2 = (zsv_ext0 = zsb);
                    dz_ext0 = dz0 - 0.3333333333333333;
                    dz_ext2 = dz0 - 0.6666666666666666;
                }
            }
            final double dx5 = dx0 - 1.0 - 0.6666666666666666;
            final double dy5 = dy0 - 1.0 - 0.6666666666666666;
            final double dz5 = dz0 - 0.0 - 0.6666666666666666;
            double attn5 = 2.0 - dx5 * dx5 - dy5 * dy5 - dz5 * dz5;
            if (attn5 > 0.0) {
                attn5 *= attn5;
                value += attn5 * attn5 * extrapolate(offsetSeed, xsb + 1, ysb + 1, zsb + 0, dx5, dy5, dz5);
            }
            final double dx6 = dx5;
            final double dy6 = dy0 - 0.0 - 0.6666666666666666;
            final double dz6 = dz0 - 1.0 - 0.6666666666666666;
            double attn6 = 2.0 - dx6 * dx6 - dy6 * dy6 - dz6 * dz6;
            if (attn6 > 0.0) {
                attn6 *= attn6;
                value += attn6 * attn6 * extrapolate(offsetSeed, xsb + 1, ysb + 0, zsb + 1, dx6, dy6, dz6);
            }
            final double dx7 = dx0 - 0.0 - 0.6666666666666666;
            final double dy7 = dy5;
            final double dz7 = dz6;
            double attn7 = 2.0 - dx7 * dx7 - dy7 * dy7 - dz7 * dz7;
            if (attn7 > 0.0) {
                attn7 *= attn7;
                value += attn7 * attn7 * extrapolate(offsetSeed, xsb + 0, ysb + 1, zsb + 1, dx7, dy7, dz7);
            }
            dx0 = dx0 - 1.0 - 1.0;
            dy0 = dy0 - 1.0 - 1.0;
            dz0 = dz0 - 1.0 - 1.0;
            double attn8 = 2.0 - dx0 * dx0 - dy0 * dy0 - dz0 * dz0;
            if (attn8 > 0.0) {
                attn8 *= attn8;
                value += attn8 * attn8 * extrapolate(offsetSeed, xsb + 1, ysb + 1, zsb + 1, dx0, dy0, dz0);
            }
        }
        else {
            final double p1 = xins + yins;
            double aScore2;
            byte aPoint2;
            boolean aIsFurtherSide;
            if (p1 > 1.0) {
                aScore2 = p1 - 1.0;
                aPoint2 = 3;
                aIsFurtherSide = true;
            }
            else {
                aScore2 = 1.0 - p1;
                aPoint2 = 4;
                aIsFurtherSide = false;
            }
            final double p2 = xins + zins;
            double bScore;
            byte bPoint2;
            boolean bIsFurtherSide;
            if (p2 > 1.0) {
                bScore = p2 - 1.0;
                bPoint2 = 5;
                bIsFurtherSide = true;
            }
            else {
                bScore = 1.0 - p2;
                bPoint2 = 2;
                bIsFurtherSide = false;
            }
            final double p3 = yins + zins;
            if (p3 > 1.0) {
                final double score = p3 - 1.0;
                if (aScore2 <= bScore && aScore2 < score) {
                    aScore2 = score;
                    aPoint2 = 6;
                    aIsFurtherSide = true;
                }
                else if (aScore2 > bScore && bScore < score) {
                    bScore = score;
                    bPoint2 = 6;
                    bIsFurtherSide = true;
                }
            }
            else {
                final double score = 1.0 - p3;
                if (aScore2 <= bScore && aScore2 < score) {
                    aScore2 = score;
                    aPoint2 = 1;
                    aIsFurtherSide = false;
                }
                else if (aScore2 > bScore && bScore < score) {
                    bScore = score;
                    bPoint2 = 1;
                    bIsFurtherSide = false;
                }
            }
            if (aIsFurtherSide == bIsFurtherSide) {
                if (aIsFurtherSide) {
                    dx_ext0 = dx0 - 1.0 - 1.0;
                    dy_ext2 = dy0 - 1.0 - 1.0;
                    dz_ext0 = dz0 - 1.0 - 1.0;
                    xsv_ext0 = xsb + 1;
                    ysv_ext2 = ysb + 1;
                    zsv_ext0 = zsb + 1;
                    final byte c2 = (byte)(aPoint2 & bPoint2);
                    if ((c2 & 0x1) != 0x0) {
                        dx_ext2 = dx0 - 2.0 - 0.6666666666666666;
                        dy_ext1 = dy0 - 0.6666666666666666;
                        dz_ext2 = dz0 - 0.6666666666666666;
                        xsv_ext2 = xsb + 2;
                        ysv_ext1 = ysb;
                        zsv_ext2 = zsb;
                    }
                    else if ((c2 & 0x2) != 0x0) {
                        dx_ext2 = dx0 - 0.6666666666666666;
                        dy_ext1 = dy0 - 2.0 - 0.6666666666666666;
                        dz_ext2 = dz0 - 0.6666666666666666;
                        xsv_ext2 = xsb;
                        ysv_ext1 = ysb + 2;
                        zsv_ext2 = zsb;
                    }
                    else {
                        dx_ext2 = dx0 - 0.6666666666666666;
                        dy_ext1 = dy0 - 0.6666666666666666;
                        dz_ext2 = dz0 - 2.0 - 0.6666666666666666;
                        xsv_ext2 = xsb;
                        ysv_ext1 = ysb;
                        zsv_ext2 = zsb + 2;
                    }
                }
                else {
                    dx_ext0 = dx0;
                    dy_ext2 = dy0;
                    dz_ext0 = dz0;
                    xsv_ext0 = xsb;
                    ysv_ext2 = ysb;
                    zsv_ext0 = zsb;
                    final byte c2 = (byte)(aPoint2 | bPoint2);
                    if ((c2 & 0x1) == 0x0) {
                        dx_ext2 = dx0 + 1.0 - 0.3333333333333333;
                        dy_ext1 = dy0 - 1.0 - 0.3333333333333333;
                        dz_ext2 = dz0 - 1.0 - 0.3333333333333333;
                        xsv_ext2 = xsb - 1;
                        ysv_ext1 = ysb + 1;
                        zsv_ext2 = zsb + 1;
                    }
                    else if ((c2 & 0x2) == 0x0) {
                        dx_ext2 = dx0 - 1.0 - 0.3333333333333333;
                        dy_ext1 = dy0 + 1.0 - 0.3333333333333333;
                        dz_ext2 = dz0 - 1.0 - 0.3333333333333333;
                        xsv_ext2 = xsb + 1;
                        ysv_ext1 = ysb - 1;
                        zsv_ext2 = zsb + 1;
                    }
                    else {
                        dx_ext2 = dx0 - 1.0 - 0.3333333333333333;
                        dy_ext1 = dy0 - 1.0 - 0.3333333333333333;
                        dz_ext2 = dz0 + 1.0 - 0.3333333333333333;
                        xsv_ext2 = xsb + 1;
                        ysv_ext1 = ysb + 1;
                        zsv_ext2 = zsb - 1;
                    }
                }
            }
            else {
                byte c3;
                byte c4;
                if (aIsFurtherSide) {
                    c3 = aPoint2;
                    c4 = bPoint2;
                }
                else {
                    c3 = bPoint2;
                    c4 = aPoint2;
                }
                if ((c3 & 0x1) == 0x0) {
                    dx_ext0 = dx0 + 1.0 - 0.3333333333333333;
                    dy_ext2 = dy0 - 1.0 - 0.3333333333333333;
                    dz_ext0 = dz0 - 1.0 - 0.3333333333333333;
                    xsv_ext0 = xsb - 1;
                    ysv_ext2 = ysb + 1;
                    zsv_ext0 = zsb + 1;
                }
                else if ((c3 & 0x2) == 0x0) {
                    dx_ext0 = dx0 - 1.0 - 0.3333333333333333;
                    dy_ext2 = dy0 + 1.0 - 0.3333333333333333;
                    dz_ext0 = dz0 - 1.0 - 0.3333333333333333;
                    xsv_ext0 = xsb + 1;
                    ysv_ext2 = ysb - 1;
                    zsv_ext0 = zsb + 1;
                }
                else {
                    dx_ext0 = dx0 - 1.0 - 0.3333333333333333;
                    dy_ext2 = dy0 - 1.0 - 0.3333333333333333;
                    dz_ext0 = dz0 + 1.0 - 0.3333333333333333;
                    xsv_ext0 = xsb + 1;
                    ysv_ext2 = ysb + 1;
                    zsv_ext0 = zsb - 1;
                }
                dx_ext2 = dx0 - 0.6666666666666666;
                dy_ext1 = dy0 - 0.6666666666666666;
                dz_ext2 = dz0 - 0.6666666666666666;
                xsv_ext2 = xsb;
                ysv_ext1 = ysb;
                zsv_ext2 = zsb;
                if ((c4 & 0x1) != 0x0) {
                    dx_ext2 -= 2.0;
                    xsv_ext2 += 2;
                }
                else if ((c4 & 0x2) != 0x0) {
                    dy_ext1 -= 2.0;
                    ysv_ext1 += 2;
                }
                else {
                    dz_ext2 -= 2.0;
                    zsv_ext2 += 2;
                }
            }
            final double dx8 = dx0 - 1.0 - 0.3333333333333333;
            final double dy8 = dy0 - 0.0 - 0.3333333333333333;
            final double dz8 = dz0 - 0.0 - 0.3333333333333333;
            double attn9 = 2.0 - dx8 * dx8 - dy8 * dy8 - dz8 * dz8;
            if (attn9 > 0.0) {
                attn9 *= attn9;
                value += attn9 * attn9 * extrapolate(offsetSeed, xsb + 1, ysb + 0, zsb + 0, dx8, dy8, dz8);
            }
            final double dx9 = dx0 - 0.0 - 0.3333333333333333;
            final double dy9 = dy0 - 1.0 - 0.3333333333333333;
            final double dz9 = dz8;
            double attn10 = 2.0 - dx9 * dx9 - dy9 * dy9 - dz9 * dz9;
            if (attn10 > 0.0) {
                attn10 *= attn10;
                value += attn10 * attn10 * extrapolate(offsetSeed, xsb + 0, ysb + 1, zsb + 0, dx9, dy9, dz9);
            }
            final double dx10 = dx9;
            final double dy10 = dy8;
            final double dz10 = dz0 - 1.0 - 0.3333333333333333;
            double attn11 = 2.0 - dx10 * dx10 - dy10 * dy10 - dz10 * dz10;
            if (attn11 > 0.0) {
                attn11 *= attn11;
                value += attn11 * attn11 * extrapolate(offsetSeed, xsb + 0, ysb + 0, zsb + 1, dx10, dy10, dz10);
            }
            final double dx11 = dx0 - 1.0 - 0.6666666666666666;
            final double dy11 = dy0 - 1.0 - 0.6666666666666666;
            final double dz11 = dz0 - 0.0 - 0.6666666666666666;
            double attn12 = 2.0 - dx11 * dx11 - dy11 * dy11 - dz11 * dz11;
            if (attn12 > 0.0) {
                attn12 *= attn12;
                value += attn12 * attn12 * extrapolate(offsetSeed, xsb + 1, ysb + 1, zsb + 0, dx11, dy11, dz11);
            }
            final double dx12 = dx11;
            final double dy12 = dy0 - 0.0 - 0.6666666666666666;
            final double dz12 = dz0 - 1.0 - 0.6666666666666666;
            double attn13 = 2.0 - dx12 * dx12 - dy12 * dy12 - dz12 * dz12;
            if (attn13 > 0.0) {
                attn13 *= attn13;
                value += attn13 * attn13 * extrapolate(offsetSeed, xsb + 1, ysb + 0, zsb + 1, dx12, dy12, dz12);
            }
            final double dx13 = dx0 - 0.0 - 0.6666666666666666;
            final double dy13 = dy11;
            final double dz13 = dz12;
            double attn14 = 2.0 - dx13 * dx13 - dy13 * dy13 - dz13 * dz13;
            if (attn14 > 0.0) {
                attn14 *= attn14;
                value += attn14 * attn14 * extrapolate(offsetSeed, xsb + 0, ysb + 1, zsb + 1, dx13, dy13, dz13);
            }
        }
        double attn_ext0 = 2.0 - dx_ext0 * dx_ext0 - dy_ext2 * dy_ext2 - dz_ext0 * dz_ext0;
        if (attn_ext0 > 0.0) {
            attn_ext0 *= attn_ext0;
            value += attn_ext0 * attn_ext0 * extrapolate(offsetSeed, xsv_ext0, ysv_ext2, zsv_ext0, dx_ext0, dy_ext2, dz_ext0);
        }
        double attn_ext2 = 2.0 - dx_ext2 * dx_ext2 - dy_ext1 * dy_ext1 - dz_ext2 * dz_ext2;
        if (attn_ext2 > 0.0) {
            attn_ext2 *= attn_ext2;
            value += attn_ext2 * attn_ext2 * extrapolate(offsetSeed, xsv_ext2, ysv_ext1, zsv_ext2, dx_ext2, dy_ext1, dz_ext2);
        }
        return value / 103.0;
    }
    
    @Nonnull
    @Override
    public String toString() {
        return "OldSimplexNoise{}";
    }
    
    private static double extrapolate(final int seed, final int x, final int y, final double xd, final double yd) {
        int hash = seed;
        hash ^= 1619 * x;
        hash ^= 31337 * y;
        hash = hash * hash * hash * 60493;
        hash ^= hash >> 13;
        final DoubleArray.Double2 g = OldSimplexNoise.gradients2D[hash & 0x7];
        return xd * g.x + yd * g.y;
    }
    
    private static double extrapolate(final int seed, final int x, final int y, final int z, final double xd, final double yd, final double zd) {
        int hash = seed;
        hash ^= 1619 * x;
        hash ^= 31337 * y;
        hash ^= 6971 * z;
        hash = hash * hash * hash * 60493;
        hash ^= hash >> 13;
        final DoubleArray.Double3 g = OldSimplexNoise.gradients3D[hash % OldSimplexNoise.gradients3D.length];
        return xd * g.x + yd * g.y + zd * g.z;
    }
    
    private static int fastFloor(final double x) {
        final int xi = (int)x;
        return (x < xi) ? (xi - 1) : xi;
    }
    
    static {
        INSTANCE = new OldSimplexNoise();
        OldSimplexNoise.gradients2D = new DoubleArray.Double2[] { new DoubleArray.Double2(5.0, 2.0), new DoubleArray.Double2(2.0, 5.0), new DoubleArray.Double2(-5.0, 2.0), new DoubleArray.Double2(-2.0, 5.0), new DoubleArray.Double2(5.0, -2.0), new DoubleArray.Double2(2.0, -5.0), new DoubleArray.Double2(-5.0, -2.0), new DoubleArray.Double2(-2.0, -5.0) };
        OldSimplexNoise.gradients3D = new DoubleArray.Double3[] { new DoubleArray.Double3(-11.0, 4.0, 4.0), new DoubleArray.Double3(-4.0, 11.0, 4.0), new DoubleArray.Double3(-4.0, 4.0, 11.0), new DoubleArray.Double3(11.0, 4.0, 4.0), new DoubleArray.Double3(4.0, 11.0, 4.0), new DoubleArray.Double3(4.0, 4.0, 11.0), new DoubleArray.Double3(-11.0, -4.0, 4.0), new DoubleArray.Double3(-4.0, -11.0, 4.0), new DoubleArray.Double3(-4.0, -4.0, 11.0), new DoubleArray.Double3(11.0, -4.0, 4.0), new DoubleArray.Double3(4.0, -11.0, 4.0), new DoubleArray.Double3(4.0, -4.0, 11.0), new DoubleArray.Double3(-11.0, 4.0, -4.0), new DoubleArray.Double3(-4.0, 11.0, -4.0), new DoubleArray.Double3(-4.0, 4.0, -11.0), new DoubleArray.Double3(11.0, 4.0, -4.0), new DoubleArray.Double3(4.0, 11.0, -4.0), new DoubleArray.Double3(4.0, 4.0, -11.0), new DoubleArray.Double3(-11.0, -4.0, -4.0), new DoubleArray.Double3(-4.0, -11.0, -4.0), new DoubleArray.Double3(-4.0, -4.0, -11.0), new DoubleArray.Double3(11.0, -4.0, -4.0), new DoubleArray.Double3(4.0, -11.0, -4.0), new DoubleArray.Double3(4.0, -4.0, -11.0) };
    }
}
