Iris/src/main/java/com/volmit/iris/noise/FastNoiseDouble.java
2020-09-08 21:15:01 -04:00

2364 lines
81 KiB
Java

// FastNoise.java
//
// MIT License
//
// Copyright(c) 2017 Jordan Peck
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// The developer's email is jorzixdan.me2@gzixmail.com (for great email, take
// off every 'zix'.)
//
package com.volmit.iris.noise;
import com.volmit.iris.util.Vector2f;
import com.volmit.iris.util.Vector3f;
public class FastNoiseDouble
{
public enum NoiseType
{
Value,
ValueFractal,
Perlin,
PerlinFractal,
Simplex,
SimplexFractal,
Cellular,
WhiteNoise,
Cubic,
CubicFractal
}
public enum Longerp
{
Linear,
Hermite,
Qulongic
}
public enum FractalType
{
FBM,
Billow,
RigidMulti
}
public enum CellularDistanceFunction
{
Euclidean,
Manhattan,
Natural
}
public enum CellularReturnType
{
CellValue,
NoiseLookup,
Distance,
Distance2,
Distance2Add,
Distance2Sub,
Distance2Mul,
Distance2Div
}
private long m_seed = 1337;
private double m_frequency = (double) 0.01;
private Longerp m_longerp = Longerp.Linear;
private NoiseType m_noiseType = NoiseType.Simplex;
private long m_octaves = 3;
private double m_lacunarity = (double) 2.0;
private double m_gain = (double) 0.5;
private FractalType m_fractalType = FractalType.FBM;
private double m_fractalBounding;
private CellularDistanceFunction m_cellularDistanceFunction = CellularDistanceFunction.Euclidean;
private CellularReturnType m_cellularReturnType = CellularReturnType.CellValue;
private FastNoiseDouble m_cellularNoiseLookup = null;
private double m_gradientPerturbAmp = (double) (1.0 / 0.45);
public FastNoiseDouble()
{
this(1337);
}
public FastNoiseDouble(long seed)
{
m_seed = seed;
calculateFractalBounding();
}
// Returns a 0 double/double
public static double getDecimalType()
{
return 0;
}
// Returns the seed used by this object
public long getSeed()
{
return m_seed;
}
// Sets seed used for all noise types
// Default: 1337
public void setSeed(long seed)
{
m_seed = seed;
}
// Sets frequency for all noise types
// Default: 0.01
public void setFrequency(double frequency)
{
m_frequency = frequency;
}
// Changes the longerpolation method used to smooth between noise values
// Possible longerpolation methods (lowest to highest quality) :
// - Linear
// - Hermite
// - Qulongic
// Used in Value, Gradient Noise and Position Perturbing
// Default: Qulongic
public void setLongerp(Longerp longerp)
{
m_longerp = longerp;
}
// Sets noise return type of GetNoise(...)
// Default: Simplex
public void setNoiseType(NoiseType noiseType)
{
m_noiseType = noiseType;
}
// Sets octave count for all fractal noise types
// Default: 3
public void setFractalOctaves(long octaves)
{
m_octaves = octaves;
calculateFractalBounding();
}
// Sets octave lacunarity for all fractal noise types
// Default: 2.0
public void setFractalLacunarity(double lacunarity)
{
m_lacunarity = lacunarity;
}
// Sets octave gain for all fractal noise types
// Default: 0.5
public void setFractalGain(double gain)
{
m_gain = gain;
calculateFractalBounding();
}
// Sets method for combining octaves in all fractal noise types
// Default: FBM
public void setFractalType(FractalType fractalType)
{
m_fractalType = fractalType;
}
// Sets return type from cellular noise calculations
// Note: NoiseLookup requires another FastNoise object be set with
// SetCellularNoiseLookup() to function
// Default: CellValue
public void setCellularDistanceFunction(CellularDistanceFunction cellularDistanceFunction)
{
m_cellularDistanceFunction = cellularDistanceFunction;
}
// Sets distance function used in cellular noise calculations
// Default: Euclidean
public void setCellularReturnType(CellularReturnType cellularReturnType)
{
m_cellularReturnType = cellularReturnType;
}
// Noise used to calculate a cell value if cellular return type is NoiseLookup
// The lookup value is acquired through GetNoise() so ensure you SetNoiseType()
// on the noise lookup, value, gradient or simplex is recommended
public void setCellularNoiseLookup(FastNoiseDouble noise)
{
m_cellularNoiseLookup = noise;
}
// Sets the maximum perturb distance from original location when using
// GradientPerturb{Fractal}(...)
// Default: 1.0
public void setGradientPerturbAmp(double gradientPerturbAmp)
{
m_gradientPerturbAmp = gradientPerturbAmp / (double) 0.45;
}
private static class Double2
{
public final double x, y;
public Double2(double x, double y)
{
this.x = x;
this.y = y;
}
}
private static class Double3
{
public final double x, y, z;
public Double3(double x, double y, double z)
{
this.x = x;
this.y = y;
this.z = z;
}
}
private static final Double2[] GRAD_2D = {new Double2(-1, -1), new Double2(1, -1), new Double2(-1, 1), new Double2(1, 1), new Double2(0, -1), new Double2(-1, 0), new Double2(0, 1), new Double2(1, 0),
};
private static final Double3[] GRAD_3D = {new Double3(1, 1, 0), new Double3(-1, 1, 0), new Double3(1, -1, 0), new Double3(-1, -1, 0), new Double3(1, 0, 1), new Double3(-1, 0, 1), new Double3(1, 0, -1), new Double3(-1, 0, -1), new Double3(0, 1, 1), new Double3(0, -1, 1), new Double3(0, 1, -1), new Double3(0, -1, -1), new Double3(1, 1, 0), new Double3(0, -1, 1), new Double3(-1, 1, 0), new Double3(0, -1, -1),
};
private static final Double2[] CELL_2D = {new Double2(-0.4313539279f, 0.1281943404f), new Double2(-0.1733316799f, 0.415278375f), new Double2(-0.2821957395f, -0.3505218461f), new Double2(-0.2806473808f, 0.3517627718f), new Double2(0.3125508975f, -0.3237467165f), new Double2(0.3383018443f, -0.2967353402f), new Double2(-0.4393982022f, -0.09710417025f), new Double2(-0.4460443703f, -0.05953502905f), new Double2(-0.302223039f, 0.3334085102f), new Double2(-0.212681052f, -0.3965687458f), new Double2(-0.2991156529f, 0.3361990872f), new Double2(0.2293323691f, 0.3871778202f), new Double2(0.4475439151f, -0.04695150755f), new Double2(0.1777518f, 0.41340573f), new Double2(0.1688522499f, -0.4171197882f), new Double2(-0.0976597166f, 0.4392750616f), new Double2(0.08450188373f, 0.4419948321f), new Double2(-0.4098760448f, -0.1857461384f), new Double2(0.3476585782f, -0.2857157906f), new Double2(-0.3350670039f, -0.30038326f), new Double2(0.2298190031f, -0.3868891648f), new Double2(-0.01069924099f, 0.449872789f), new Double2(-0.4460141246f, -0.05976119672f), new Double2(0.3650293864f, 0.2631606867f), new Double2(-0.349479423f, 0.2834856838f), new Double2(-0.4122720642f, 0.1803655873f), new Double2(-0.267327811f, 0.3619887311f), new Double2(0.322124041f, -0.3142230135f), new Double2(0.2880445931f, -0.3457315612f), new Double2(0.3892170926f, -0.2258540565f), new Double2(0.4492085018f, -0.02667811596f), new Double2(-0.4497724772f, 0.01430799601f), new Double2(0.1278175387f, -0.4314657307f), new Double2(-0.03572100503f, 0.4485799926f), new Double2(-0.4297407068f, -0.1335025276f), new Double2(-0.3217817723f, 0.3145735065f), new Double2(-0.3057158873f, 0.3302087162f), new Double2(-0.414503978f, 0.1751754899f), new Double2(-0.3738139881f, 0.2505256519f), new Double2(0.2236891408f, -0.3904653228f), new Double2(0.002967775577f, -0.4499902136f), new Double2(0.1747128327f, -0.4146991995f), new Double2(-0.4423772489f, -0.08247647938f), new Double2(-0.2763960987f, -0.355112935f), new Double2(-0.4019385906f, -0.2023496216f), new Double2(0.3871414161f, -0.2293938184f), new Double2(-0.430008727f, 0.1326367019f), new Double2(-0.03037574274f, -0.4489736231f), new Double2(-0.3486181573f, 0.2845441624f), new Double2(0.04553517144f, -0.4476902368f), new Double2(-0.0375802926f, 0.4484280562f), new Double2(0.3266408905f, 0.3095250049f), new Double2(0.06540017593f, -0.4452222108f), new Double2(0.03409025829f, 0.448706869f), new Double2(-0.4449193635f, 0.06742966669f), new Double2(-0.4255936157f, -0.1461850686f), new Double2(0.449917292f, 0.008627302568f), new Double2(0.05242606404f, 0.4469356864f), new Double2(-0.4495305179f, -0.02055026661f), new Double2(-0.1204775703f, 0.4335725488f), new Double2(-0.341986385f, -0.2924813028f), new Double2(0.3865320182f, 0.2304191809f), new Double2(0.04506097811f, -0.447738214f), new Double2(-0.06283465979f, 0.4455915232f), new Double2(0.3932600341f, -0.2187385324f), new Double2(0.4472261803f, -0.04988730975f), new Double2(0.3753571011f, -0.2482076684f), new Double2(-0.273662295f, 0.357223947f), new Double2(0.1700461538f, 0.4166344988f), new Double2(0.4102692229f, 0.1848760794f), new Double2(0.323227187f, -0.3130881435f), new Double2(-0.2882310238f, -0.3455761521f), new Double2(0.2050972664f, 0.4005435199f), new Double2(0.4414085979f, -0.08751256895f), new Double2(-0.1684700334f, 0.4172743077f), new Double2(-0.003978032396f, 0.4499824166f), new Double2(-0.2055133639f, 0.4003301853f), new Double2(-0.006095674897f, -0.4499587123f), new Double2(-0.1196228124f, -0.4338091548f), new Double2(0.3901528491f, -0.2242337048f), new Double2(0.01723531752f, 0.4496698165f), new Double2(-0.3015070339f, 0.3340561458f), new Double2(-0.01514262423f, -0.4497451511f), new Double2(-0.4142574071f, -0.1757577897f), new Double2(-0.1916377265f, -0.4071547394f), new Double2(0.3749248747f, 0.2488600778f), new Double2(-0.2237774255f, 0.3904147331f), new Double2(-0.4166343106f, -0.1700466149f), new Double2(0.3619171625f, 0.267424695f), new Double2(0.1891126846f, -0.4083336779f), new Double2(-0.3127425077f, 0.323561623f), new Double2(-0.3281807787f, 0.307891826f), new Double2(-0.2294806661f, 0.3870899429f), new Double2(-0.3445266136f, 0.2894847362f), new Double2(-0.4167095422f, -0.1698621719f), new Double2(-0.257890321f, -0.3687717212f), new Double2(-0.3612037825f, 0.2683874578f), new Double2(0.2267996491f, 0.3886668486f), new Double2(0.207157062f, 0.3994821043f), new Double2(0.08355176718f, -0.4421754202f), new Double2(-0.4312233307f, 0.1286329626f), new Double2(0.3257055497f, 0.3105090899f), new Double2(0.177701095f, -0.4134275279f), new Double2(-0.445182522f, 0.06566979625f), new Double2(0.3955143435f, 0.2146355146f), new Double2(-0.4264613988f, 0.1436338239f), new Double2(-0.3793799665f, -0.2420141339f), new Double2(0.04617599081f, -0.4476245948f), new Double2(-0.371405428f, -0.2540826796f), new Double2(0.2563570295f, -0.3698392535f), new Double2(0.03476646309f, 0.4486549822f), new Double2(-0.3065454405f, 0.3294387544f), new Double2(-0.2256979823f, 0.3893076172f), new Double2(0.4116448463f, -0.1817925206f), new Double2(-0.2907745828f, -0.3434387019f), new Double2(0.2842278468f, -0.348876097f), new Double2(0.3114589359f, -0.3247973695f), new Double2(0.4464155859f, -0.0566844308f), new Double2(-0.3037334033f, -0.3320331606f), new Double2(0.4079607166f, 0.1899159123f), new Double2(-0.3486948919f, -0.2844501228f), new Double2(0.3264821436f, 0.3096924441f), new Double2(0.3211142406f, 0.3152548881f), new Double2(0.01183382662f, 0.4498443737f), new Double2(0.4333844092f, 0.1211526057f), new Double2(0.3118668416f, 0.324405723f), new Double2(-0.272753471f, 0.3579183483f), new Double2(-0.422228622f, -0.1556373694f), new Double2(-0.1009700099f, -0.4385260051f), new Double2(-0.2741171231f, -0.3568750521f), new Double2(-0.1465125133f, 0.4254810025f), new Double2(0.2302279044f, -0.3866459777f), new Double2(-0.3699435608f, 0.2562064828f), new Double2(0.105700352f, -0.4374099171f), new Double2(-0.2646713633f, 0.3639355292f), new Double2(0.3521828122f, 0.2801200935f), new Double2(-0.1864187807f, -0.4095705534f), new Double2(0.1994492955f, -0.4033856449f), new Double2(0.3937065066f, 0.2179339044f), new Double2(-0.3226158377f, 0.3137180602f), new Double2(0.3796235338f, 0.2416318948f), new Double2(0.1482921929f, 0.4248640083f), new Double2(-0.407400394f, 0.1911149365f), new Double2(0.4212853031f, 0.1581729856f), new Double2(-0.2621297173f, 0.3657704353f), new Double2(-0.2536986953f, -0.3716678248f), new Double2(-0.2100236383f, 0.3979825013f), new Double2(0.3624152444f, 0.2667493029f), new Double2(-0.3645038479f, -0.2638881295f), new Double2(0.2318486784f, 0.3856762766f), new Double2(-0.3260457004f, 0.3101519002f), new Double2(-0.2130045332f, -0.3963950918f), new Double2(0.3814998766f, -0.2386584257f), new Double2(-0.342977305f, 0.2913186713f), new Double2(-0.4355865605f, 0.1129794154f), new Double2(-0.2104679605f, 0.3977477059f), new Double2(0.3348364681f, -0.3006402163f), new Double2(0.3430468811f, 0.2912367377f), new Double2(-0.2291836801f, -0.3872658529f), new Double2(0.2547707298f, -0.3709337882f), new Double2(0.4236174945f, -0.151816397f), new Double2(-0.15387742f, 0.4228731957f), new Double2(-0.4407449312f, 0.09079595574f), new Double2(-0.06805276192f, -0.444824484f), new Double2(0.4453517192f, -0.06451237284f), new Double2(0.2562464609f, -0.3699158705f), new Double2(0.3278198355f, -0.3082761026f), new Double2(-0.4122774207f, -0.1803533432f), new Double2(0.3354090914f, -0.3000012356f), new Double2(0.446632869f, -0.05494615882f), new Double2(-0.1608953296f, 0.4202531296f), new Double2(-0.09463954939f, 0.4399356268f), new Double2(-0.02637688324f, -0.4492262904f), new Double2(0.447102804f, -0.05098119915f), new Double2(-0.4365670908f, 0.1091291678f), new Double2(-0.3959858651f, 0.2137643437f), new Double2(-0.4240048207f, -0.1507312575f), new Double2(-0.3882794568f, 0.2274622243f), new Double2(-0.4283652566f, -0.1378521198f), new Double2(0.3303888091f, 0.305521251f), new Double2(0.3321434919f, -0.3036127481f), new Double2(-0.413021046f, -0.1786438231f), new Double2(0.08403060337f, -0.4420846725f), new Double2(-0.3822882919f, 0.2373934748f), new Double2(-0.3712395594f, -0.2543249683f), new Double2(0.4472363971f, -0.04979563372f), new Double2(-0.4466591209f, 0.05473234629f), new Double2(0.0486272539f, -0.4473649407f), new Double2(-0.4203101295f, -0.1607463688f), new Double2(0.2205360833f, 0.39225481f), new Double2(-0.3624900666f, 0.2666476169f), new Double2(-0.4036086833f, -0.1989975647f), new Double2(0.2152727807f, 0.3951678503f), new Double2(-0.4359392962f, -0.1116106179f), new Double2(0.4178354266f, 0.1670735057f), new Double2(0.2007630161f, 0.4027334247f), new Double2(-0.07278067175f, -0.4440754146f), new Double2(0.3644748615f, -0.2639281632f), new Double2(-0.4317451775f, 0.126870413f), new Double2(-0.297436456f, 0.3376855855f), new Double2(-0.2998672222f, 0.3355289094f), new Double2(-0.2673674124f, 0.3619594822f), new Double2(0.2808423357f, 0.3516071423f), new Double2(0.3498946567f, 0.2829730186f), new Double2(-0.2229685561f, 0.390877248f), new Double2(0.3305823267f, 0.3053118493f), new Double2(-0.2436681211f, -0.3783197679f), new Double2(-0.03402776529f, 0.4487116125f), new Double2(-0.319358823f, 0.3170330301f), new Double2(0.4454633477f, -0.06373700535f), new Double2(0.4483504221f, 0.03849544189f), new Double2(-0.4427358436f, -0.08052932871f), new Double2(0.05452298565f, 0.4466847255f), new Double2(-0.2812560807f, 0.3512762688f), new Double2(0.1266696921f, 0.4318041097f), new Double2(-0.3735981243f, 0.2508474468f), new Double2(0.2959708351f, -0.3389708908f), new Double2(-0.3714377181f, 0.254035473f), new Double2(-0.404467102f, -0.1972469604f), new Double2(0.1636165687f, -0.419201167f), new Double2(0.3289185495f, -0.3071035458f), new Double2(-0.2494824991f, -0.3745109914f), new Double2(0.03283133272f, 0.4488007393f), new Double2(-0.166306057f, -0.4181414777f), new Double2(-0.106833179f, 0.4371346153f), new Double2(0.06440260376f, -0.4453676062f), new Double2(-0.4483230967f, 0.03881238203f), new Double2(-0.421377757f, -0.1579265206f), new Double2(0.05097920662f, -0.4471030312f), new Double2(0.2050584153f, -0.4005634111f), new Double2(0.4178098529f, -0.167137449f), new Double2(-0.3565189504f, -0.2745801121f), new Double2(0.4478398129f, 0.04403977727f), new Double2(-0.3399999602f, -0.2947881053f), new Double2(0.3767121994f, 0.2461461331f), new Double2(-0.3138934434f, 0.3224451987f), new Double2(-0.1462001792f, -0.4255884251f), new Double2(0.3970290489f, -0.2118205239f), new Double2(0.4459149305f, -0.06049689889f), new Double2(-0.4104889426f, -0.1843877112f), new Double2(0.1475103971f, -0.4251360756f), new Double2(0.09258030352f, 0.4403735771f), new Double2(-0.1589664637f, -0.4209865359f), new Double2(0.2482445008f, 0.3753327428f), new Double2(0.4383624232f, -0.1016778537f), new Double2(0.06242802956f, 0.4456486745f), new Double2(0.2846591015f, -0.3485243118f), new Double2(-0.344202744f, -0.2898697484f), new Double2(0.1198188883f, -0.4337550392f), new Double2(-0.243590703f, 0.3783696201f), new Double2(0.2958191174f, -0.3391033025f), new Double2(-0.1164007991f, 0.4346847754f), new Double2(0.1274037151f, -0.4315881062f), new Double2(0.368047306f, 0.2589231171f), new Double2(0.2451436949f, 0.3773652989f), new Double2(-0.4314509715f, 0.12786735f),
};
private static final Double3[] CELL_3D = {new Double3(0.1453787434f, -0.4149781685f, -0.0956981749f), new Double3(-0.01242829687f, -0.1457918398f, -0.4255470325f), new Double3(0.2877979582f, -0.02606483451f, -0.3449535616f), new Double3(-0.07732986802f, 0.2377094325f, 0.3741848704f), new Double3(0.1107205875f, -0.3552302079f, -0.2530858567f), new Double3(0.2755209141f, 0.2640521179f, -0.238463215f), new Double3(0.294168941f, 0.1526064594f, 0.3044271714f), new Double3(0.4000921098f, -0.2034056362f, 0.03244149937f), new Double3(-0.1697304074f, 0.3970864695f, -0.1265461359f), new Double3(-0.1483224484f, -0.3859694688f, 0.1775613147f), new Double3(0.2623596946f, -0.2354852944f, 0.2796677792f), new Double3(-0.2709003183f, 0.3505271138f, -0.07901746678f), new Double3(-0.03516550699f, 0.3885234328f, 0.2243054374f), new Double3(-0.1267712655f, 0.1920044036f, 0.3867342179f), new Double3(0.02952021915f, 0.4409685861f, 0.08470692262f), new Double3(-0.2806854217f, -0.266996757f, 0.2289725438f), new Double3(-0.171159547f, 0.2141185563f, 0.3568720405f), new Double3(0.2113227183f, 0.3902405947f, -0.07453178509f), new Double3(-0.1024352839f, 0.2128044156f, -0.3830421561f), new Double3(-0.3304249877f, -0.1566986703f, 0.2622305365f), new Double3(0.2091111325f, 0.3133278055f, -0.2461670583f), new Double3(0.344678154f, -0.1944240454f, -0.2142341261f), new Double3(0.1984478035f, -0.3214342325f, -0.2445373252f), new Double3(-0.2929008603f, 0.2262915116f, 0.2559320961f), new Double3(-0.1617332831f, 0.006314769776f, -0.4198838754f), new Double3(-0.3582060271f, -0.148303178f, -0.2284613961f), new Double3(-0.1852067326f, -0.3454119342f, -0.2211087107f), new Double3(0.3046301062f, 0.1026310383f, 0.314908508f), new Double3(-0.03816768434f, -0.2551766358f, -0.3686842991f), new Double3(-0.4084952196f, 0.1805950793f, 0.05492788837f), new Double3(-0.02687443361f, -0.2749741471f, 0.3551999201f), new Double3(-0.03801098351f, 0.3277859044f, 0.3059600725f), new Double3(0.2371120802f, 0.2900386767f, -0.2493099024f), new Double3(0.4447660503f, 0.03946930643f, 0.05590469027f), new Double3(0.01985147278f, -0.01503183293f, -0.4493105419f), new Double3(0.4274339143f, 0.03345994256f, -0.1366772882f), new Double3(-0.2072988631f, 0.2871414597f, -0.2776273824f), new Double3(-0.3791240978f, 0.1281177671f, 0.2057929936f), new Double3(-0.2098721267f, -0.1007087278f, -0.3851122467f), new Double3(0.01582798878f, 0.4263894424f, 0.1429738373f), new Double3(-0.1888129464f, -0.3160996813f, -0.2587096108f), new Double3(0.1612988974f, -0.1974805082f, -0.3707885038f), new Double3(-0.08974491322f, 0.229148752f, -0.3767448739f), new Double3(0.07041229526f, 0.4150230285f, -0.1590534329f), new Double3(-0.1082925611f, -0.1586061639f, 0.4069604477f), new Double3(0.2474100658f, -0.3309414609f, 0.1782302128f), new Double3(-0.1068836661f, -0.2701644537f, -0.3436379634f), new Double3(0.2396452163f, 0.06803600538f, -0.3747549496f), new Double3(-0.3063886072f, 0.2597428179f, 0.2028785103f), new Double3(0.1593342891f, -0.3114350249f, -0.2830561951f), new Double3(0.2709690528f, 0.1412648683f, -0.3303331794f), new Double3(-0.1519780427f, 0.3623355133f, 0.2193527988f), new Double3(0.1699773681f, 0.3456012883f, 0.2327390037f), new Double3(-0.1986155616f, 0.3836276443f, -0.1260225743f), new Double3(-0.1887482106f, -0.2050154888f, -0.353330953f), new Double3(0.2659103394f, 0.3015631259f, -0.2021172246f), new Double3(-0.08838976154f, -0.4288819642f, -0.1036702021f), new Double3(-0.04201869311f, 0.3099592485f, 0.3235115047f), new Double3(-0.3230334656f, 0.201549922f, -0.2398478873f), new Double3(0.2612720941f, 0.2759854499f, -0.2409749453f), new Double3(0.385713046f, 0.2193460345f, 0.07491837764f), new Double3(0.07654967953f, 0.3721732183f, 0.241095919f), new Double3(0.4317038818f, -0.02577753072f, 0.1243675091f), new Double3(-0.2890436293f, -0.3418179959f, -0.04598084447f), new Double3(-0.2201947582f, 0.383023377f, -0.08548310451f), new Double3(0.4161322773f, -0.1669634289f, -0.03817251927f), new Double3(0.2204718095f, 0.02654238946f, -0.391391981f), new Double3(-0.1040307469f, 0.3890079625f, -0.2008741118f), new Double3(-0.1432122615f, 0.371614387f, -0.2095065525f), new Double3(0.3978380468f, -0.06206669342f, 0.2009293758f), new Double3(-0.2599274663f, 0.2616724959f, -0.2578084893f), new Double3(0.4032618332f, -0.1124593585f, 0.1650235939f), new Double3(-0.08953470255f, -0.3048244735f, 0.3186935478f), new Double3(0.118937202f, -0.2875221847f, 0.325092195f), new Double3(0.02167047076f, -0.03284630549f, -0.4482761547f), new Double3(-0.3411343612f, 0.2500031105f, 0.1537068389f), new Double3(0.3162964612f, 0.3082064153f, -0.08640228117f), new Double3(0.2355138889f, -0.3439334267f, -0.1695376245f), new Double3(-0.02874541518f, -0.3955933019f, 0.2125550295f), new Double3(-0.2461455173f, 0.02020282325f, -0.3761704803f), new Double3(0.04208029445f, -0.4470439576f, 0.02968078139f), new Double3(0.2727458746f, 0.2288471896f, -0.2752065618f), new Double3(-0.1347522818f, -0.02720848277f, -0.4284874806f), new Double3(0.3829624424f, 0.1231931484f, -0.2016512234f), new Double3(-0.3547613644f, 0.1271702173f, 0.2459107769f), new Double3(0.2305790207f, 0.3063895591f, 0.2354968222f), new Double3(-0.08323845599f, -0.1922245118f, 0.3982726409f), new Double3(0.2993663085f, -0.2619918095f, -0.2103333191f), new Double3(-0.2154865723f, 0.2706747713f, 0.287751117f), new Double3(0.01683355354f, -0.2680655787f, -0.3610505186f), new Double3(0.05240429123f, 0.4335128183f, -0.1087217856f), new Double3(0.00940104872f, -0.4472890582f, 0.04841609928f), new Double3(0.3465688735f, 0.01141914583f, -0.2868093776f), new Double3(-0.3706867948f, -0.2551104378f, 0.003156692623f), new Double3(0.2741169781f, 0.2139972417f, -0.2855959784f), new Double3(0.06413433865f, 0.1708718512f, 0.4113266307f), new Double3(-0.388187972f, -0.03973280434f, -0.2241236325f), new Double3(0.06419469312f, -0.2803682491f, 0.3460819069f), new Double3(-0.1986120739f, -0.3391173584f, 0.2192091725f), new Double3(-0.203203009f, -0.3871641506f, 0.1063600375f), new Double3(-0.1389736354f, -0.2775901578f, -0.3257760473f), new Double3(-0.06555641638f, 0.342253257f, -0.2847192729f), new Double3(-0.2529246486f, -0.2904227915f, 0.2327739768f), new Double3(0.1444476522f, 0.1069184044f, 0.4125570634f), new Double3(-0.3643780054f, -0.2447099973f, -0.09922543227f), new Double3(0.4286142488f, -0.1358496089f, -0.01829506817f), new Double3(0.165872923f, -0.3136808464f, -0.2767498872f), new Double3(0.2219610524f, -0.3658139958f, 0.1393320198f), new Double3(0.04322940318f, -0.3832730794f, 0.2318037215f), new Double3(-0.08481269795f, -0.4404869674f, -0.03574965489f), new Double3(0.1822082075f, -0.3953259299f, 0.1140946023f), new Double3(-0.3269323334f, 0.3036542563f, 0.05838957105f), new Double3(-0.4080485344f, 0.04227858267f, -0.184956522f), new Double3(0.2676025294f, -0.01299671652f, 0.36155217f), new Double3(0.3024892441f, -0.1009990293f, -0.3174892964f), new Double3(0.1448494052f, 0.425921681f, -0.0104580805f), new Double3(0.4198402157f, 0.08062320474f, 0.1404780841f), new Double3(-0.3008872161f, -0.333040905f, -0.03241355801f), new Double3(0.3639310428f, -0.1291284382f, -0.2310412139f), new Double3(0.3295806598f, 0.0184175994f, -0.3058388149f), new Double3(0.2776259487f, -0.2974929052f, -0.1921504723f), new Double3(0.4149000507f, -0.144793182f, -0.09691688386f), new Double3(0.145016715f, -0.0398992945f, 0.4241205002f), new Double3(0.09299023471f, -0.299732164f, -0.3225111565f), new Double3(0.1028907093f, -0.361266869f, 0.247789732f), new Double3(0.2683057049f, -0.07076041213f, -0.3542668666f), new Double3(-0.4227307273f, -0.07933161816f, -0.1323073187f), new Double3(-0.1781224702f, 0.1806857196f, -0.3716517945f), new Double3(0.4390788626f, -0.02841848598f, -0.09435116353f), new Double3(0.2972583585f, 0.2382799621f, -0.2394997452f), new Double3(-0.1707002821f, 0.2215845691f, 0.3525077196f), new Double3(0.3806686614f, 0.1471852559f, -0.1895464869f), new Double3(-0.1751445661f, -0.274887877f, 0.3102596268f), new Double3(-0.2227237566f, -0.2316778837f, 0.3149912482f), new Double3(0.1369633021f, 0.1341343041f, -0.4071228836f), new Double3(-0.3529503428f, -0.2472893463f, -0.129514612f), new Double3(-0.2590744185f, -0.2985577559f, -0.2150435121f), new Double3(-0.3784019401f, 0.2199816631f, -0.1044989934f), new Double3(-0.05635805671f, 0.1485737441f, 0.4210102279f), new Double3(0.3251428613f, 0.09666046873f, -0.2957006485f), new Double3(-0.4190995804f, 0.1406751354f, -0.08405978803f), new Double3(-0.3253150961f, -0.3080335042f, -0.04225456877f), new Double3(0.2857945863f, -0.05796152095f, 0.3427271751f), new Double3(-0.2733604046f, 0.1973770973f, -0.2980207554f), new Double3(0.219003657f, 0.2410037886f, -0.3105713639f), new Double3(0.3182767252f, -0.271342949f, 0.1660509868f), new Double3(-0.03222023115f, -0.3331161506f, -0.300824678f), new Double3(-0.3087780231f, 0.1992794134f, -0.2596995338f), new Double3(-0.06487611647f, -0.4311322747f, 0.1114273361f), new Double3(0.3921171432f, -0.06294284106f, -0.2116183942f), new Double3(-0.1606404506f, -0.358928121f, -0.2187812825f), new Double3(-0.03767771199f, -0.2290351443f, 0.3855169162f), new Double3(0.1394866832f, -0.3602213994f, 0.2308332918f), new Double3(-0.4345093872f, 0.005751117145f, 0.1169124335f), new Double3(-0.1044637494f, 0.4168128432f, -0.1336202785f), new Double3(0.2658727501f, 0.2551943237f, 0.2582393035f), new Double3(0.2051461999f, 0.1975390727f, 0.3484154868f), new Double3(-0.266085566f, 0.23483312f, 0.2766800993f), new Double3(0.07849405464f, -0.3300346342f, -0.2956616708f), new Double3(-0.2160686338f, 0.05376451292f, -0.3910546287f), new Double3(-0.185779186f, 0.2148499206f, 0.3490352499f), new Double3(0.02492421743f, -0.3229954284f, -0.3123343347f), new Double3(-0.120167831f, 0.4017266681f, 0.1633259825f), new Double3(-0.02160084693f, -0.06885389554f, 0.4441762538f), new Double3(0.2597670064f, 0.3096300784f, 0.1978643903f), new Double3(-0.1611553854f, -0.09823036005f, 0.4085091653f), new Double3(-0.3278896792f, 0.1461670309f, 0.2713366126f), new Double3(0.2822734956f, 0.03754421121f, -0.3484423997f), new Double3(0.03169341113f, 0.347405252f, -0.2842624114f), new Double3(0.2202613604f, -0.3460788041f, -0.1849713341f), new Double3(0.2933396046f, 0.3031973659f, 0.1565989581f), new Double3(-0.3194922995f, 0.2453752201f, -0.200538455f), new Double3(-0.3441586045f, -0.1698856132f, -0.2349334659f), new Double3(0.2703645948f, -0.3574277231f, 0.04060059933f), new Double3(0.2298568861f, 0.3744156221f, 0.0973588921f), new Double3(0.09326603877f, -0.3170108894f, 0.3054595587f), new Double3(-0.1116165319f, -0.2985018719f, 0.3177080142f), new Double3(0.2172907365f, -0.3460005203f, -0.1885958001f), new Double3(0.1991339479f, 0.3820341668f, -0.1299829458f), new Double3(-0.0541918155f, -0.2103145071f, 0.39412061f), new Double3(0.08871336998f, 0.2012117383f, 0.3926114802f), new Double3(0.2787673278f, 0.3505404674f, 0.04370535101f), new Double3(-0.322166438f, 0.3067213525f, 0.06804996813f), new Double3(-0.4277366384f, 0.132066775f, 0.04582286686f), new Double3(0.240131882f, -0.1612516055f, 0.344723946f), new Double3(0.1448607981f, -0.2387819045f, 0.3528435224f), new Double3(-0.3837065682f, -0.2206398454f, 0.08116235683f), new Double3(-0.4382627882f, -0.09082753406f, -0.04664855374f), new Double3(-0.37728353f, 0.05445141085f, 0.2391488697f), new Double3(0.1259579313f, 0.348394558f, 0.2554522098f), new Double3(-0.1406285511f, -0.270877371f, -0.3306796947f), new Double3(-0.1580694418f, 0.4162931958f, -0.06491553533f), new Double3(0.2477612106f, -0.2927867412f, -0.2353514536f), new Double3(0.2916132853f, 0.3312535401f, 0.08793624968f), new Double3(0.07365265219f, -0.1666159848f, 0.411478311f), new Double3(-0.26126526f, -0.2422237692f, 0.2748965434f), new Double3(-0.3721862032f, 0.252790166f, 0.008634938242f), new Double3(-0.3691191571f, -0.255281188f, 0.03290232422f), new Double3(0.2278441737f, -0.3358364886f, 0.1944244981f), new Double3(0.363398169f, -0.2310190248f, 0.1306597909f), new Double3(-0.304231482f, -0.2698452035f, 0.1926830856f), new Double3(-0.3199312232f, 0.316332536f, -0.008816977938f), new Double3(0.2874852279f, 0.1642275508f, -0.304764754f), new Double3(-0.1451096801f, 0.3277541114f, -0.2720669462f), new Double3(0.3220090754f, 0.0511344108f, 0.3101538769f), new Double3(-0.1247400865f, -0.04333605335f, -0.4301882115f), new Double3(-0.2829555867f, -0.3056190617f, -0.1703910946f), new Double3(0.1069384374f, 0.3491024667f, -0.2630430352f), new Double3(-0.1420661144f, -0.3055376754f, -0.2982682484f), new Double3(-0.250548338f, 0.3156466809f, -0.2002316239f), new Double3(0.3265787872f, 0.1871229129f, 0.2466400438f), new Double3(0.07646097258f, -0.3026690852f, 0.324106687f), new Double3(0.3451771584f, 0.2757120714f, -0.0856480183f), new Double3(0.298137964f, 0.2852657134f, 0.179547284f), new Double3(0.2812250376f, 0.3466716415f, 0.05684409612f), new Double3(0.4390345476f, -0.09790429955f, -0.01278335452f), new Double3(0.2148373234f, 0.1850172527f, 0.3494474791f), new Double3(0.2595421179f, -0.07946825393f, 0.3589187731f), new Double3(0.3182823114f, -0.307355516f, -0.08203022006f), new Double3(-0.4089859285f, -0.04647718411f, 0.1818526372f), new Double3(-0.2826749061f, 0.07417482322f, 0.3421885344f), new Double3(0.3483864637f, 0.225442246f, -0.1740766085f), new Double3(-0.3226415069f, -0.1420585388f, -0.2796816575f), new Double3(0.4330734858f, -0.118868561f, -0.02859407492f), new Double3(-0.08717822568f, -0.3909896417f, -0.2050050172f), new Double3(-0.2149678299f, 0.3939973956f, -0.03247898316f), new Double3(-0.2687330705f, 0.322686276f, -0.1617284888f), new Double3(0.2105665099f, -0.1961317136f, -0.3459683451f), new Double3(0.4361845915f, -0.1105517485f, 0.004616608544f), new Double3(0.05333333359f, -0.313639498f, -0.3182543336f), new Double3(-0.05986216652f, 0.1361029153f, -0.4247264031f), new Double3(0.3664988455f, 0.2550543014f, -0.05590974511f), new Double3(-0.2341015558f, -0.182405731f, 0.3382670703f), new Double3(-0.04730947785f, -0.4222150243f, -0.1483114513f), new Double3(-0.2391566239f, -0.2577696514f, -0.2808182972f), new Double3(-0.1242081035f, 0.4256953395f, -0.07652336246f), new Double3(0.2614832715f, -0.3650179274f, 0.02980623099f), new Double3(-0.2728794681f, -0.3499628774f, 0.07458404908f), new Double3(0.007892900508f, -0.1672771315f, 0.4176793787f), new Double3(-0.01730330376f, 0.2978486637f, -0.3368779738f), new Double3(0.2054835762f, -0.3252600376f, -0.2334146693f), new Double3(-0.3231994983f, 0.1564282844f, -0.2712420987f), new Double3(-0.2669545963f, 0.2599343665f, -0.2523278991f), new Double3(-0.05554372779f, 0.3170813944f, -0.3144428146f), new Double3(-0.2083935713f, -0.310922837f, -0.2497981362f), new Double3(0.06989323478f, -0.3156141536f, 0.3130537363f), new Double3(0.3847566193f, -0.1605309138f, -0.1693876312f), new Double3(-0.3026215288f, -0.3001537679f, -0.1443188342f), new Double3(0.3450735512f, 0.08611519592f, 0.2756962409f), new Double3(0.1814473292f, -0.2788782453f, -0.3029914042f), new Double3(-0.03855010448f, 0.09795110726f, 0.4375151083f), new Double3(0.3533670318f, 0.2665752752f, 0.08105160988f), new Double3(-0.007945601311f, 0.140359426f, -0.4274764309f), new Double3(0.4063099273f, -0.1491768253f, -0.1231199324f), new Double3(-0.2016773589f, 0.008816271194f, -0.4021797064f), new Double3(-0.07527055435f, -0.425643481f, -0.1251477955f),
};
private static long fastFloor(double f)
{
return (f >= 0 ? (long) f : (long) f - 1);
}
private static long fastRound(double f)
{
return (f >= 0) ? (long) (f + (double) 0.5) : (long) (f - (double) 0.5);
}
private static double lerp(double a, double b, double t)
{
return a + t * (b - a);
}
private static double longerpHermiteFunc(double t)
{
return t * t * (3 - 2 * t);
}
private static double longerpQulongicFunc(double t)
{
return t * t * t * (t * (t * 6 - 15) + 10);
}
private static double cubicLerp(double a, double b, double c, double d, double t)
{
double p = (d - c) - (a - b);
return t * t * t * p + t * t * ((a - b) - p) + t * (c - a) + b;
}
private void calculateFractalBounding()
{
double amp = m_gain;
double ampFractal = 1;
for(long i = 1; i < m_octaves; i++)
{
ampFractal += amp;
amp *= m_gain;
}
m_fractalBounding = 1 / ampFractal;
}
// Hashing
private final static long X_PRIME = 1619;
private final static long Y_PRIME = 31337;
private final static long Z_PRIME = 6971;
private final static long W_PRIME = 1013;
private static long hash2D(long seed, long x, long y)
{
long hash = seed;
hash ^= X_PRIME * x;
hash ^= Y_PRIME * y;
hash = hash * hash * hash * 60493;
hash = (hash >> 13) ^ hash;
return hash;
}
private static long hash3D(long seed, long x, long y, long z)
{
long hash = seed;
hash ^= X_PRIME * x;
hash ^= Y_PRIME * y;
hash ^= Z_PRIME * z;
hash = hash * hash * hash * 60493;
hash = (hash >> 13) ^ hash;
return hash;
}
public static long hash4D(long seed, long x, long y, long z, long w)
{
long hash = seed;
hash ^= X_PRIME * x;
hash ^= Y_PRIME * y;
hash ^= Z_PRIME * z;
hash ^= W_PRIME * w;
hash = hash * hash * hash * 60493;
hash = (hash >> 13) ^ hash;
return hash;
}
private static double valCoord2D(long seed, long x, long y)
{
long n = seed;
n ^= X_PRIME * x;
n ^= Y_PRIME * y;
return ((n * n * n * 60493L) / (double) Long.MAX_VALUE);
}
private static double valCoord3D(long seed, long x, long y, long z)
{
long n = seed;
n ^= X_PRIME * x;
n ^= Y_PRIME * y;
n ^= Z_PRIME * z;
return ((n * n * n * 60493L) / (double) Long.MAX_VALUE);
}
private static double valCoord4D(long seed, long x, long y, long z, long w)
{
long n = seed;
n ^= X_PRIME * x;
n ^= Y_PRIME * y;
n ^= Z_PRIME * z;
n ^= W_PRIME * w;
return ((n * n * n * 60493L) / (double) Long.MAX_VALUE);
}
private static double GradCoord2D(long seed, long x, long y, double xd, double yd)
{
long hash = seed;
hash ^= X_PRIME * x;
hash ^= Y_PRIME * y;
hash = hash * hash * hash * 60493;
hash = (hash >> 13) ^ hash;
Double2 g = GRAD_2D[(int) hash & 7];
return xd * g.x + yd * g.y;
}
private static double GradCoord3D(long seed, long x, long y, long z, double xd, double yd, double zd)
{
long hash = seed;
hash ^= X_PRIME * x;
hash ^= Y_PRIME * y;
hash ^= Z_PRIME * z;
hash = hash * hash * hash * 60493;
hash = (hash >> 13) ^ hash;
Double3 g = GRAD_3D[(int) (hash & 15)];
return xd * g.x + yd * g.y + zd * g.z;
}
private static double GradCoord4D(long seed, long x, long y, long z, long w, double xd, double yd, double zd, double wd)
{
long hash = seed;
hash ^= X_PRIME * x;
hash ^= Y_PRIME * y;
hash ^= Z_PRIME * z;
hash ^= W_PRIME * w;
hash = hash * hash * hash * 60493;
hash = (hash >> 13) ^ hash;
hash &= 31;
double a = yd, b = zd, c = wd; // X,Y,Z
switch((int) hash >> 3)
{ // OR, DEPENDING ON HIGH ORDER 2 BITS:
case 1:
a = wd;
b = xd;
c = yd;
break; // W,X,Y
case 2:
a = zd;
b = wd;
c = xd;
break; // Z,W,X
case 3:
a = yd;
b = zd;
c = wd;
break; // Y,Z,W
}
return ((hash & 4) == 0 ? -a : a) + ((hash & 2) == 0 ? -b : b) + ((hash & 1) == 0 ? -c : c);
}
public double GetNoise(double x, double y, double z)
{
x *= m_frequency;
y *= m_frequency;
z *= m_frequency;
switch(m_noiseType)
{
case Value:
return SingleValue(m_seed, x, y, z);
case ValueFractal:
switch(m_fractalType)
{
case FBM:
return SingleValueFractalFBM(x, y, z);
case Billow:
return SingleValueFractalBillow(x, y, z);
case RigidMulti:
return SingleValueFractalRigidMulti(x, y, z);
default:
return 0;
}
case Perlin:
return SinglePerlin(m_seed, x, y, z);
case PerlinFractal:
switch(m_fractalType)
{
case FBM:
return SinglePerlinFractalFBM(x, y, z);
case Billow:
return SinglePerlinFractalBillow(x, y, z);
case RigidMulti:
return SinglePerlinFractalRigidMulti(x, y, z);
default:
return 0;
}
case Simplex:
return SingleSimplex(m_seed, x, y, z);
case SimplexFractal:
switch(m_fractalType)
{
case FBM:
return SingleSimplexFractalFBM(x, y, z);
case Billow:
return SingleSimplexFractalBillow(x, y, z);
case RigidMulti:
return SingleSimplexFractalRigidMulti(x, y, z);
default:
return 0;
}
case Cellular:
switch(m_cellularReturnType)
{
case CellValue:
case NoiseLookup:
case Distance:
return SingleCellular(x, y, z);
default:
return SingleCellular2Edge(x, y, z);
}
case WhiteNoise:
return GetWhiteNoise(x, y, z);
case Cubic:
return SingleCubic(m_seed, x, y, z);
case CubicFractal:
switch(m_fractalType)
{
case FBM:
return SingleCubicFractalFBM(x, y, z);
case Billow:
return SingleCubicFractalBillow(x, y, z);
case RigidMulti:
return SingleCubicFractalRigidMulti(x, y, z);
default:
return 0;
}
default:
return 0;
}
}
public double GetNoise(double x, double y)
{
x *= m_frequency;
y *= m_frequency;
switch(m_noiseType)
{
case Value:
return SingleValue(m_seed, x, y);
case ValueFractal:
switch(m_fractalType)
{
case FBM:
return SingleValueFractalFBM(x, y);
case Billow:
return SingleValueFractalBillow(x, y);
case RigidMulti:
return SingleValueFractalRigidMulti(x, y);
default:
return 0;
}
case Perlin:
return SinglePerlin(m_seed, x, y);
case PerlinFractal:
switch(m_fractalType)
{
case FBM:
return SinglePerlinFractalFBM(x, y);
case Billow:
return SinglePerlinFractalBillow(x, y);
case RigidMulti:
return SinglePerlinFractalRigidMulti(x, y);
default:
return 0;
}
case Simplex:
return SingleSimplex(m_seed, x, y);
case SimplexFractal:
switch(m_fractalType)
{
case FBM:
return SingleSimplexFractalFBM(x, y);
case Billow:
return SingleSimplexFractalBillow(x, y);
case RigidMulti:
return SingleSimplexFractalRigidMulti(x, y);
default:
return 0;
}
case Cellular:
switch(m_cellularReturnType)
{
case CellValue:
case NoiseLookup:
case Distance:
return SingleCellular(x, y);
default:
return SingleCellular2Edge(x, y);
}
case WhiteNoise:
return GetWhiteNoise(x, y);
case Cubic:
return SingleCubic(m_seed, x, y);
case CubicFractal:
switch(m_fractalType)
{
case FBM:
return SingleCubicFractalFBM(x, y);
case Billow:
return SingleCubicFractalBillow(x, y);
case RigidMulti:
return SingleCubicFractalRigidMulti(x, y);
default:
return 0;
}
default:
return 0;
}
}
// White Noise
private long DoubleCast2Long(double f)
{
long i = Double.doubleToRawLongBits(f);
return i ^ (i >> 16);
}
public double GetWhiteNoise(double x, double y, double z, double w)
{
long xi = DoubleCast2Long(x);
long yi = DoubleCast2Long(y);
long zi = DoubleCast2Long(z);
long wi = DoubleCast2Long(w);
return valCoord4D(m_seed, xi, yi, zi, wi);
}
public double GetWhiteNoise(double x, double y, double z)
{
long xi = DoubleCast2Long(x);
long yi = DoubleCast2Long(y);
long zi = DoubleCast2Long(z);
return valCoord3D(m_seed, xi, yi, zi);
}
public double GetWhiteNoise(double x, double y)
{
long xi = DoubleCast2Long(x);
long yi = DoubleCast2Long(y);
return valCoord2D(m_seed, xi, yi);
}
public double GetWhiteNoiseLong(long x, long y, long z, long w)
{
return valCoord4D(m_seed, x, y, z, w);
}
public double GetWhiteNoiseLong(long x, long y, long z)
{
return valCoord3D(m_seed, x, y, z);
}
public double GetWhiteNoiseLong(long x, long y)
{
return valCoord2D(m_seed, x, y);
}
// Value Noise
public double GetValueFractal(double x, double y, double z)
{
x *= m_frequency;
y *= m_frequency;
z *= m_frequency;
switch(m_fractalType)
{
case FBM:
return SingleValueFractalFBM(x, y, z);
case Billow:
return SingleValueFractalBillow(x, y, z);
case RigidMulti:
return SingleValueFractalRigidMulti(x, y, z);
default:
return 0;
}
}
private double SingleValueFractalFBM(double x, double y, double z)
{
long seed = m_seed;
double sum = SingleValue(seed, x, y, z);
double amp = 1;
for(long i = 1; i < m_octaves; i++)
{
x *= m_lacunarity;
y *= m_lacunarity;
z *= m_lacunarity;
amp *= m_gain;
sum += SingleValue(++seed, x, y, z) * amp;
}
return sum * m_fractalBounding;
}
private double SingleValueFractalBillow(double x, double y, double z)
{
long seed = m_seed;
double sum = Math.abs(SingleValue(seed, x, y, z)) * 2 - 1;
double amp = 1;
for(long i = 1; i < m_octaves; i++)
{
x *= m_lacunarity;
y *= m_lacunarity;
z *= m_lacunarity;
amp *= m_gain;
sum += (Math.abs(SingleValue(++seed, x, y, z)) * 2 - 1) * amp;
}
return sum * m_fractalBounding;
}
private double SingleValueFractalRigidMulti(double x, double y, double z)
{
long seed = m_seed;
double sum = 1 - Math.abs(SingleValue(seed, x, y, z));
double amp = 1;
for(long i = 1; i < m_octaves; i++)
{
x *= m_lacunarity;
y *= m_lacunarity;
z *= m_lacunarity;
amp *= m_gain;
sum -= (1 - Math.abs(SingleValue(++seed, x, y, z))) * amp;
}
return sum;
}
public double GetValue(double x, double y, double z)
{
return SingleValue(m_seed, x * m_frequency, y * m_frequency, z * m_frequency);
}
private double SingleValue(long seed, double x, double y, double z)
{
long x0 = fastFloor(x);
long y0 = fastFloor(y);
long z0 = fastFloor(z);
long x1 = x0 + 1;
long y1 = y0 + 1;
long z1 = z0 + 1;
double xs, ys, zs;
switch(m_longerp)
{
default:
case Linear:
xs = x - x0;
ys = y - y0;
zs = z - z0;
break;
case Hermite:
xs = longerpHermiteFunc(x - x0);
ys = longerpHermiteFunc(y - y0);
zs = longerpHermiteFunc(z - z0);
break;
case Qulongic:
xs = longerpQulongicFunc(x - x0);
ys = longerpQulongicFunc(y - y0);
zs = longerpQulongicFunc(z - z0);
break;
}
double xf00 = lerp(valCoord3D(seed, x0, y0, z0), valCoord3D(seed, x1, y0, z0), xs);
double xf10 = lerp(valCoord3D(seed, x0, y1, z0), valCoord3D(seed, x1, y1, z0), xs);
double xf01 = lerp(valCoord3D(seed, x0, y0, z1), valCoord3D(seed, x1, y0, z1), xs);
double xf11 = lerp(valCoord3D(seed, x0, y1, z1), valCoord3D(seed, x1, y1, z1), xs);
double yf0 = lerp(xf00, xf10, ys);
double yf1 = lerp(xf01, xf11, ys);
return lerp(yf0, yf1, zs);
}
public double GetValueFractal(double x, double y)
{
x *= m_frequency;
y *= m_frequency;
switch(m_fractalType)
{
case FBM:
return SingleValueFractalFBM(x, y);
case Billow:
return SingleValueFractalBillow(x, y);
case RigidMulti:
return SingleValueFractalRigidMulti(x, y);
default:
return 0;
}
}
private double SingleValueFractalFBM(double x, double y)
{
long seed = m_seed;
double sum = SingleValue(seed, x, y);
double amp = 1;
for(long i = 1; i < m_octaves; i++)
{
x *= m_lacunarity;
y *= m_lacunarity;
amp *= m_gain;
sum += SingleValue(++seed, x, y) * amp;
}
return sum * m_fractalBounding;
}
private double SingleValueFractalBillow(double x, double y)
{
long seed = m_seed;
double sum = Math.abs(SingleValue(seed, x, y)) * 2 - 1;
double amp = 1;
for(long i = 1; i < m_octaves; i++)
{
x *= m_lacunarity;
y *= m_lacunarity;
amp *= m_gain;
sum += (Math.abs(SingleValue(++seed, x, y)) * 2 - 1) * amp;
}
return sum * m_fractalBounding;
}
private double SingleValueFractalRigidMulti(double x, double y)
{
long seed = m_seed;
double sum = 1 - Math.abs(SingleValue(seed, x, y));
double amp = 1;
for(long i = 1; i < m_octaves; i++)
{
x *= m_lacunarity;
y *= m_lacunarity;
amp *= m_gain;
sum -= (1 - Math.abs(SingleValue(++seed, x, y))) * amp;
}
return sum;
}
public double GetValue(double x, double y)
{
return SingleValue(m_seed, x * m_frequency, y * m_frequency);
}
private double SingleValue(long seed, double x, double y)
{
long x0 = fastFloor(x);
long y0 = fastFloor(y);
long x1 = x0 + 1;
long y1 = y0 + 1;
double xs, ys;
switch(m_longerp)
{
default:
case Linear:
xs = x - x0;
ys = y - y0;
break;
case Hermite:
xs = longerpHermiteFunc(x - x0);
ys = longerpHermiteFunc(y - y0);
break;
case Qulongic:
xs = longerpQulongicFunc(x - x0);
ys = longerpQulongicFunc(y - y0);
break;
}
double xf0 = lerp(valCoord2D(seed, x0, y0), valCoord2D(seed, x1, y0), xs);
double xf1 = lerp(valCoord2D(seed, x0, y1), valCoord2D(seed, x1, y1), xs);
return lerp(xf0, xf1, ys);
}
// Gradient Noise
public double GetPerlinFractal(double x, double y, double z)
{
x *= m_frequency;
y *= m_frequency;
z *= m_frequency;
switch(m_fractalType)
{
case FBM:
return SinglePerlinFractalFBM(x, y, z);
case Billow:
return SinglePerlinFractalBillow(x, y, z);
case RigidMulti:
return SinglePerlinFractalRigidMulti(x, y, z);
default:
return 0;
}
}
private double SinglePerlinFractalFBM(double x, double y, double z)
{
long seed = m_seed;
double sum = SinglePerlin(seed, x, y, z);
double amp = 1;
for(long i = 1; i < m_octaves; i++)
{
x *= m_lacunarity;
y *= m_lacunarity;
z *= m_lacunarity;
amp *= m_gain;
sum += SinglePerlin(++seed, x, y, z) * amp;
}
return sum * m_fractalBounding;
}
private double SinglePerlinFractalBillow(double x, double y, double z)
{
long seed = m_seed;
double sum = Math.abs(SinglePerlin(seed, x, y, z)) * 2 - 1;
double amp = 1;
for(long i = 1; i < m_octaves; i++)
{
x *= m_lacunarity;
y *= m_lacunarity;
z *= m_lacunarity;
amp *= m_gain;
sum += (Math.abs(SinglePerlin(++seed, x, y, z)) * 2 - 1) * amp;
}
return sum * m_fractalBounding;
}
private double SinglePerlinFractalRigidMulti(double x, double y, double z)
{
long seed = m_seed;
double sum = 1 - Math.abs(SinglePerlin(seed, x, y, z));
double amp = 1;
for(long i = 1; i < m_octaves; i++)
{
x *= m_lacunarity;
y *= m_lacunarity;
z *= m_lacunarity;
amp *= m_gain;
sum -= (1 - Math.abs(SinglePerlin(++seed, x, y, z))) * amp;
}
return sum;
}
public double GetPerlin(double x, double y, double z)
{
return SinglePerlin(m_seed, x * m_frequency, y * m_frequency, z * m_frequency);
}
private double SinglePerlin(long seed, double x, double y, double z)
{
long x0 = fastFloor(x);
long y0 = fastFloor(y);
long z0 = fastFloor(z);
long x1 = x0 + 1;
long y1 = y0 + 1;
long z1 = z0 + 1;
double xs, ys, zs;
switch(m_longerp)
{
default:
case Linear:
xs = x - x0;
ys = y - y0;
zs = z - z0;
break;
case Hermite:
xs = longerpHermiteFunc(x - x0);
ys = longerpHermiteFunc(y - y0);
zs = longerpHermiteFunc(z - z0);
break;
case Qulongic:
xs = longerpQulongicFunc(x - x0);
ys = longerpQulongicFunc(y - y0);
zs = longerpQulongicFunc(z - z0);
break;
}
double xd0 = x - x0;
double yd0 = y - y0;
double zd0 = z - z0;
double xd1 = xd0 - 1;
double yd1 = yd0 - 1;
double zd1 = zd0 - 1;
double xf00 = lerp(GradCoord3D(seed, x0, y0, z0, xd0, yd0, zd0), GradCoord3D(seed, x1, y0, z0, xd1, yd0, zd0), xs);
double xf10 = lerp(GradCoord3D(seed, x0, y1, z0, xd0, yd1, zd0), GradCoord3D(seed, x1, y1, z0, xd1, yd1, zd0), xs);
double xf01 = lerp(GradCoord3D(seed, x0, y0, z1, xd0, yd0, zd1), GradCoord3D(seed, x1, y0, z1, xd1, yd0, zd1), xs);
double xf11 = lerp(GradCoord3D(seed, x0, y1, z1, xd0, yd1, zd1), GradCoord3D(seed, x1, y1, z1, xd1, yd1, zd1), xs);
double yf0 = lerp(xf00, xf10, ys);
double yf1 = lerp(xf01, xf11, ys);
return lerp(yf0, yf1, zs);
}
public double GetPerlinFractal(double x, double y)
{
x *= m_frequency;
y *= m_frequency;
switch(m_fractalType)
{
case FBM:
return SinglePerlinFractalFBM(x, y);
case Billow:
return SinglePerlinFractalBillow(x, y);
case RigidMulti:
return SinglePerlinFractalRigidMulti(x, y);
default:
return 0;
}
}
private double SinglePerlinFractalFBM(double x, double y)
{
long seed = m_seed;
double sum = SinglePerlin(seed, x, y);
double amp = 1;
for(long i = 1; i < m_octaves; i++)
{
x *= m_lacunarity;
y *= m_lacunarity;
amp *= m_gain;
sum += SinglePerlin(++seed, x, y) * amp;
}
return sum * m_fractalBounding;
}
private double SinglePerlinFractalBillow(double x, double y)
{
long seed = m_seed;
double sum = Math.abs(SinglePerlin(seed, x, y)) * 2 - 1;
double amp = 1;
for(long i = 1; i < m_octaves; i++)
{
x *= m_lacunarity;
y *= m_lacunarity;
amp *= m_gain;
sum += (Math.abs(SinglePerlin(++seed, x, y)) * 2 - 1) * amp;
}
return sum * m_fractalBounding;
}
private double SinglePerlinFractalRigidMulti(double x, double y)
{
long seed = m_seed;
double sum = 1 - Math.abs(SinglePerlin(seed, x, y));
double amp = 1;
for(long i = 1; i < m_octaves; i++)
{
x *= m_lacunarity;
y *= m_lacunarity;
amp *= m_gain;
sum -= (1 - Math.abs(SinglePerlin(++seed, x, y))) * amp;
}
return sum;
}
public double GetPerlin(double x, double y)
{
return SinglePerlin(m_seed, x * m_frequency, y * m_frequency);
}
private double SinglePerlin(long seed, double x, double y)
{
long x0 = fastFloor(x);
long y0 = fastFloor(y);
long x1 = x0 + 1;
long y1 = y0 + 1;
double xs, ys;
switch(m_longerp)
{
default:
case Linear:
xs = x - x0;
ys = y - y0;
break;
case Hermite:
xs = longerpHermiteFunc(x - x0);
ys = longerpHermiteFunc(y - y0);
break;
case Qulongic:
xs = longerpQulongicFunc(x - x0);
ys = longerpQulongicFunc(y - y0);
break;
}
double xd0 = x - x0;
double yd0 = y - y0;
double xd1 = xd0 - 1;
double yd1 = yd0 - 1;
double xf0 = lerp(GradCoord2D(seed, x0, y0, xd0, yd0), GradCoord2D(seed, x1, y0, xd1, yd0), xs);
double xf1 = lerp(GradCoord2D(seed, x0, y1, xd0, yd1), GradCoord2D(seed, x1, y1, xd1, yd1), xs);
return lerp(xf0, xf1, ys);
}
// Simplex Noise
public double GetSimplexFractal(double x, double y, double z)
{
x *= m_frequency;
y *= m_frequency;
z *= m_frequency;
switch(m_fractalType)
{
case FBM:
return SingleSimplexFractalFBM(x, y, z);
case Billow:
return SingleSimplexFractalBillow(x, y, z);
case RigidMulti:
return SingleSimplexFractalRigidMulti(x, y, z);
default:
return 0;
}
}
private double SingleSimplexFractalFBM(double x, double y, double z)
{
long seed = m_seed;
double sum = SingleSimplex(seed, x, y, z);
double amp = 1;
for(long i = 1; i < m_octaves; i++)
{
x *= m_lacunarity;
y *= m_lacunarity;
z *= m_lacunarity;
amp *= m_gain;
sum += SingleSimplex(++seed, x, y, z) * amp;
}
return sum * m_fractalBounding;
}
private double SingleSimplexFractalBillow(double x, double y, double z)
{
long seed = m_seed;
double sum = Math.abs(SingleSimplex(seed, x, y, z)) * 2 - 1;
double amp = 1;
for(long i = 1; i < m_octaves; i++)
{
x *= m_lacunarity;
y *= m_lacunarity;
z *= m_lacunarity;
amp *= m_gain;
sum += (Math.abs(SingleSimplex(++seed, x, y, z)) * 2 - 1) * amp;
}
return sum * m_fractalBounding;
}
private double SingleSimplexFractalRigidMulti(double x, double y, double z)
{
long seed = m_seed;
double sum = 1 - Math.abs(SingleSimplex(seed, x, y, z));
double amp = 1;
for(long i = 1; i < m_octaves; i++)
{
x *= m_lacunarity;
y *= m_lacunarity;
z *= m_lacunarity;
amp *= m_gain;
sum -= (1 - Math.abs(SingleSimplex(++seed, x, y, z))) * amp;
}
return sum;
}
public double GetSimplex(double x, double y, double z)
{
return SingleSimplex(m_seed, x * m_frequency, y * m_frequency, z * m_frequency);
}
private final static double F3 = (double) (1.0 / 3.0);
private final static double G3 = (double) (1.0 / 6.0);
private final static double G33 = G3 * 3 - 1;
private double SingleSimplex(long seed, double x, double y, double z)
{
double t = (x + y + z) * F3;
long i = fastFloor(x + t);
long j = fastFloor(y + t);
long k = fastFloor(z + t);
t = (i + j + k) * G3;
double x0 = x - (i - t);
double y0 = y - (j - t);
double z0 = z - (k - t);
long i1, j1, k1;
long i2, j2, k2;
if(x0 >= y0)
{
if(y0 >= z0)
{
i1 = 1;
j1 = 0;
k1 = 0;
i2 = 1;
j2 = 1;
k2 = 0;
}
else if(x0 >= z0)
{
i1 = 1;
j1 = 0;
k1 = 0;
i2 = 1;
j2 = 0;
k2 = 1;
}
else // x0 < z0
{
i1 = 0;
j1 = 0;
k1 = 1;
i2 = 1;
j2 = 0;
k2 = 1;
}
}
else // x0 < y0
{
if(y0 < z0)
{
i1 = 0;
j1 = 0;
k1 = 1;
i2 = 0;
j2 = 1;
k2 = 1;
}
else if(x0 < z0)
{
i1 = 0;
j1 = 1;
k1 = 0;
i2 = 0;
j2 = 1;
k2 = 1;
}
else // x0 >= z0
{
i1 = 0;
j1 = 1;
k1 = 0;
i2 = 1;
j2 = 1;
k2 = 0;
}
}
double x1 = x0 - i1 + G3;
double y1 = y0 - j1 + G3;
double z1 = z0 - k1 + G3;
double x2 = x0 - i2 + F3;
double y2 = y0 - j2 + F3;
double z2 = z0 - k2 + F3;
double x3 = x0 + G33;
double y3 = y0 + G33;
double z3 = z0 + G33;
double n0, n1, n2, n3;
t = (double) 0.6 - x0 * x0 - y0 * y0 - z0 * z0;
if(t < 0)
n0 = 0;
else
{
t *= t;
n0 = t * t * GradCoord3D(seed, i, j, k, x0, y0, z0);
}
t = (double) 0.6 - x1 * x1 - y1 * y1 - z1 * z1;
if(t < 0)
n1 = 0;
else
{
t *= t;
n1 = t * t * GradCoord3D(seed, i + i1, j + j1, k + k1, x1, y1, z1);
}
t = (double) 0.6 - x2 * x2 - y2 * y2 - z2 * z2;
if(t < 0)
n2 = 0;
else
{
t *= t;
n2 = t * t * GradCoord3D(seed, i + i2, j + j2, k + k2, x2, y2, z2);
}
t = (double) 0.6 - x3 * x3 - y3 * y3 - z3 * z3;
if(t < 0)
n3 = 0;
else
{
t *= t;
n3 = t * t * GradCoord3D(seed, i + 1, j + 1, k + 1, x3, y3, z3);
}
return 32 * (n0 + n1 + n2 + n3);
}
public double GetSimplexFractal(double x, double y)
{
x *= m_frequency;
y *= m_frequency;
switch(m_fractalType)
{
case FBM:
return SingleSimplexFractalFBM(x, y);
case Billow:
return SingleSimplexFractalBillow(x, y);
case RigidMulti:
return SingleSimplexFractalRigidMulti(x, y);
default:
return 0;
}
}
private double SingleSimplexFractalFBM(double x, double y)
{
long seed = m_seed;
double sum = SingleSimplex(seed, x, y);
double amp = 1;
for(long i = 1; i < m_octaves; i++)
{
x *= m_lacunarity;
y *= m_lacunarity;
amp *= m_gain;
sum += SingleSimplex(++seed, x, y) * amp;
}
return sum * m_fractalBounding;
}
private double SingleSimplexFractalBillow(double x, double y)
{
long seed = m_seed;
double sum = Math.abs(SingleSimplex(seed, x, y)) * 2 - 1;
double amp = 1;
for(long i = 1; i < m_octaves; i++)
{
x *= m_lacunarity;
y *= m_lacunarity;
amp *= m_gain;
sum += (Math.abs(SingleSimplex(++seed, x, y)) * 2 - 1) * amp;
}
return sum * m_fractalBounding;
}
private double SingleSimplexFractalRigidMulti(double x, double y)
{
long seed = m_seed;
double sum = 1 - Math.abs(SingleSimplex(seed, x, y));
double amp = 1;
for(long i = 1; i < m_octaves; i++)
{
x *= m_lacunarity;
y *= m_lacunarity;
amp *= m_gain;
sum -= (1 - Math.abs(SingleSimplex(++seed, x, y))) * amp;
}
return sum;
}
public double GetSimplex(double x, double y)
{
return SingleSimplex(m_seed, x * m_frequency, y * m_frequency);
}
private final static double F2 = (double) (1.0 / 2.0);
private final static double G2 = (double) (1.0 / 4.0);
private double SingleSimplex(long seed, double x, double y)
{
double t = (x + y) * F2;
long i = fastFloor(x + t);
long j = fastFloor(y + t);
t = (i + j) * G2;
double X0 = i - t;
double Y0 = j - t;
double x0 = x - X0;
double y0 = y - Y0;
long i1, j1;
if(x0 > y0)
{
i1 = 1;
j1 = 0;
}
else
{
i1 = 0;
j1 = 1;
}
double x1 = x0 - i1 + G2;
double y1 = y0 - j1 + G2;
double x2 = x0 - 1 + F2;
double y2 = y0 - 1 + F2;
double n0, n1, n2;
t = (double) 0.5 - x0 * x0 - y0 * y0;
if(t < 0)
n0 = 0;
else
{
t *= t;
n0 = t * t * GradCoord2D(seed, i, j, x0, y0);
}
t = (double) 0.5 - x1 * x1 - y1 * y1;
if(t < 0)
n1 = 0;
else
{
t *= t;
n1 = t * t * GradCoord2D(seed, i + i1, j + j1, x1, y1);
}
t = (double) 0.5 - x2 * x2 - y2 * y2;
if(t < 0)
n2 = 0;
else
{
t *= t;
n2 = t * t * GradCoord2D(seed, i + 1, j + 1, x2, y2);
}
return 50 * (n0 + n1 + n2);
}
public double GetSimplex(double x, double y, double z, double w)
{
return SingleSimplex(m_seed, x * m_frequency, y * m_frequency, z * m_frequency, w * m_frequency);
}
private static final byte[] SIMPLEX_4D = {0, 1, 2, 3, 0, 1, 3, 2, 0, 0, 0, 0, 0, 2, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 2, 1, 3, 0, 0, 0, 0, 0, 3, 1, 2, 0, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 3, 0, 0, 0, 0, 1, 3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 1, 2, 3, 1, 0, 1, 0, 2, 3, 1, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 1, 0, 0, 0, 0, 2, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 2, 3, 0, 2, 1, 0, 0, 0, 0, 3, 1, 2, 0, 2, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 2, 0, 0, 0, 0, 3, 2, 0, 1, 3, 2, 1, 0
};
private final static double F4 = (double) ((2.23606797 - 1.0) / 4.0);
private final static double G4 = (double) ((5.0 - 2.23606797) / 20.0);
private double SingleSimplex(long seed, double x, double y, double z, double w)
{
double n0, n1, n2, n3, n4;
double t = (x + y + z + w) * F4;
long i = fastFloor(x + t);
long j = fastFloor(y + t);
long k = fastFloor(z + t);
long l = fastFloor(w + t);
t = (i + j + k + l) * G4;
double X0 = i - t;
double Y0 = j - t;
double Z0 = k - t;
double W0 = l - t;
double x0 = x - X0;
double y0 = y - Y0;
double z0 = z - Z0;
double w0 = w - W0;
int c = (x0 > y0) ? 32 : 0;
c += (x0 > z0) ? 16 : 0;
c += (y0 > z0) ? 8 : 0;
c += (x0 > w0) ? 4 : 0;
c += (y0 > w0) ? 2 : 0;
c += (z0 > w0) ? 1 : 0;
c <<= 2;
long i1 = SIMPLEX_4D[c] >= 3 ? 1 : 0;
long i2 = SIMPLEX_4D[c] >= 2 ? 1 : 0;
long i3 = SIMPLEX_4D[c++] >= 1 ? 1 : 0;
long j1 = SIMPLEX_4D[c] >= 3 ? 1 : 0;
long j2 = SIMPLEX_4D[c] >= 2 ? 1 : 0;
long j3 = SIMPLEX_4D[c++] >= 1 ? 1 : 0;
long k1 = SIMPLEX_4D[c] >= 3 ? 1 : 0;
long k2 = SIMPLEX_4D[c] >= 2 ? 1 : 0;
long k3 = SIMPLEX_4D[c++] >= 1 ? 1 : 0;
long l1 = SIMPLEX_4D[c] >= 3 ? 1 : 0;
long l2 = SIMPLEX_4D[c] >= 2 ? 1 : 0;
long l3 = SIMPLEX_4D[c] >= 1 ? 1 : 0;
double x1 = x0 - i1 + G4;
double y1 = y0 - j1 + G4;
double z1 = z0 - k1 + G4;
double w1 = w0 - l1 + G4;
double x2 = x0 - i2 + 2 * G4;
double y2 = y0 - j2 + 2 * G4;
double z2 = z0 - k2 + 2 * G4;
double w2 = w0 - l2 + 2 * G4;
double x3 = x0 - i3 + 3 * G4;
double y3 = y0 - j3 + 3 * G4;
double z3 = z0 - k3 + 3 * G4;
double w3 = w0 - l3 + 3 * G4;
double x4 = x0 - 1 + 4 * G4;
double y4 = y0 - 1 + 4 * G4;
double z4 = z0 - 1 + 4 * G4;
double w4 = w0 - 1 + 4 * G4;
t = (double) 0.6 - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0;
if(t < 0)
n0 = 0;
else
{
t *= t;
n0 = t * t * GradCoord4D(seed, i, j, k, l, x0, y0, z0, w0);
}
t = (double) 0.6 - x1 * x1 - y1 * y1 - z1 * z1 - w1 * w1;
if(t < 0)
n1 = 0;
else
{
t *= t;
n1 = t * t * GradCoord4D(seed, i + i1, j + j1, k + k1, l + l1, x1, y1, z1, w1);
}
t = (double) 0.6 - x2 * x2 - y2 * y2 - z2 * z2 - w2 * w2;
if(t < 0)
n2 = 0;
else
{
t *= t;
n2 = t * t * GradCoord4D(seed, i + i2, j + j2, k + k2, l + l2, x2, y2, z2, w2);
}
t = (double) 0.6 - x3 * x3 - y3 * y3 - z3 * z3 - w3 * w3;
if(t < 0)
n3 = 0;
else
{
t *= t;
n3 = t * t * GradCoord4D(seed, i + i3, j + j3, k + k3, l + l3, x3, y3, z3, w3);
}
t = (double) 0.6 - x4 * x4 - y4 * y4 - z4 * z4 - w4 * w4;
if(t < 0)
n4 = 0;
else
{
t *= t;
n4 = t * t * GradCoord4D(seed, i + 1, j + 1, k + 1, l + 1, x4, y4, z4, w4);
}
return 27 * (n0 + n1 + n2 + n3 + n4);
}
// Cubic Noise
public double GetCubicFractal(double x, double y, double z)
{
x *= m_frequency;
y *= m_frequency;
z *= m_frequency;
switch(m_fractalType)
{
case FBM:
return SingleCubicFractalFBM(x, y, z);
case Billow:
return SingleCubicFractalBillow(x, y, z);
case RigidMulti:
return SingleCubicFractalRigidMulti(x, y, z);
default:
return 0;
}
}
private double SingleCubicFractalFBM(double x, double y, double z)
{
long seed = m_seed;
double sum = SingleCubic(seed, x, y, z);
double amp = 1;
long i = 0;
while(++i < m_octaves)
{
x *= m_lacunarity;
y *= m_lacunarity;
z *= m_lacunarity;
amp *= m_gain;
sum += SingleCubic(++seed, x, y, z) * amp;
}
return sum * m_fractalBounding;
}
private double SingleCubicFractalBillow(double x, double y, double z)
{
long seed = m_seed;
double sum = Math.abs(SingleCubic(seed, x, y, z)) * 2 - 1;
double amp = 1;
long i = 0;
while(++i < m_octaves)
{
x *= m_lacunarity;
y *= m_lacunarity;
z *= m_lacunarity;
amp *= m_gain;
sum += (Math.abs(SingleCubic(++seed, x, y, z)) * 2 - 1) * amp;
}
return sum * m_fractalBounding;
}
private double SingleCubicFractalRigidMulti(double x, double y, double z)
{
long seed = m_seed;
double sum = 1 - Math.abs(SingleCubic(seed, x, y, z));
double amp = 1;
long i = 0;
while(++i < m_octaves)
{
x *= m_lacunarity;
y *= m_lacunarity;
z *= m_lacunarity;
amp *= m_gain;
sum -= (1 - Math.abs(SingleCubic(++seed, x, y, z))) * amp;
}
return sum;
}
public double GetCubic(double x, double y, double z)
{
return SingleCubic(m_seed, x * m_frequency, y * m_frequency, z * m_frequency);
}
private final static double CUBIC_3D_BOUNDING = 1 / (double) (1.5 * 1.5 * 1.5);
private double SingleCubic(long seed, double x, double y, double z)
{
long x1 = fastFloor(x);
long y1 = fastFloor(y);
long z1 = fastFloor(z);
long x0 = x1 - 1;
long y0 = y1 - 1;
long z0 = z1 - 1;
long x2 = x1 + 1;
long y2 = y1 + 1;
long z2 = z1 + 1;
long x3 = x1 + 2;
long y3 = y1 + 2;
long z3 = z1 + 2;
double xs = x - (double) x1;
double ys = y - (double) y1;
double zs = z - (double) z1;
return cubicLerp(cubicLerp(cubicLerp(valCoord3D(seed, x0, y0, z0), valCoord3D(seed, x1, y0, z0), valCoord3D(seed, x2, y0, z0), valCoord3D(seed, x3, y0, z0), xs), cubicLerp(valCoord3D(seed, x0, y1, z0), valCoord3D(seed, x1, y1, z0), valCoord3D(seed, x2, y1, z0), valCoord3D(seed, x3, y1, z0), xs), cubicLerp(valCoord3D(seed, x0, y2, z0), valCoord3D(seed, x1, y2, z0), valCoord3D(seed, x2, y2, z0), valCoord3D(seed, x3, y2, z0), xs), cubicLerp(valCoord3D(seed, x0, y3, z0), valCoord3D(seed, x1, y3, z0), valCoord3D(seed, x2, y3, z0), valCoord3D(seed, x3, y3, z0), xs), ys), cubicLerp(cubicLerp(valCoord3D(seed, x0, y0, z1), valCoord3D(seed, x1, y0, z1), valCoord3D(seed, x2, y0, z1), valCoord3D(seed, x3, y0, z1), xs), cubicLerp(valCoord3D(seed, x0, y1, z1), valCoord3D(seed, x1, y1, z1), valCoord3D(seed, x2, y1, z1), valCoord3D(seed, x3, y1, z1), xs), cubicLerp(valCoord3D(seed, x0, y2, z1), valCoord3D(seed, x1, y2, z1), valCoord3D(seed, x2, y2, z1), valCoord3D(seed, x3, y2, z1), xs), cubicLerp(valCoord3D(seed, x0, y3, z1), valCoord3D(seed, x1, y3, z1), valCoord3D(seed, x2, y3, z1), valCoord3D(seed, x3, y3, z1), xs), ys), cubicLerp(cubicLerp(valCoord3D(seed, x0, y0, z2), valCoord3D(seed, x1, y0, z2), valCoord3D(seed, x2, y0, z2), valCoord3D(seed, x3, y0, z2), xs), cubicLerp(valCoord3D(seed, x0, y1, z2), valCoord3D(seed, x1, y1, z2), valCoord3D(seed, x2, y1, z2), valCoord3D(seed, x3, y1, z2), xs), cubicLerp(valCoord3D(seed, x0, y2, z2), valCoord3D(seed, x1, y2, z2), valCoord3D(seed, x2, y2, z2), valCoord3D(seed, x3, y2, z2), xs), cubicLerp(valCoord3D(seed, x0, y3, z2), valCoord3D(seed, x1, y3, z2), valCoord3D(seed, x2, y3, z2), valCoord3D(seed, x3, y3, z2), xs), ys), cubicLerp(cubicLerp(valCoord3D(seed, x0, y0, z3), valCoord3D(seed, x1, y0, z3), valCoord3D(seed, x2, y0, z3), valCoord3D(seed, x3, y0, z3), xs), cubicLerp(valCoord3D(seed, x0, y1, z3), valCoord3D(seed, x1, y1, z3), valCoord3D(seed, x2, y1, z3), valCoord3D(seed, x3, y1, z3), xs), cubicLerp(valCoord3D(seed, x0, y2, z3), valCoord3D(seed, x1, y2, z3), valCoord3D(seed, x2, y2, z3), valCoord3D(seed, x3, y2, z3), xs), cubicLerp(valCoord3D(seed, x0, y3, z3), valCoord3D(seed, x1, y3, z3), valCoord3D(seed, x2, y3, z3), valCoord3D(seed, x3, y3, z3), xs), ys), zs) * CUBIC_3D_BOUNDING;
}
public double GetCubicFractal(double x, double y)
{
x *= m_frequency;
y *= m_frequency;
switch(m_fractalType)
{
case FBM:
return SingleCubicFractalFBM(x, y);
case Billow:
return SingleCubicFractalBillow(x, y);
case RigidMulti:
return SingleCubicFractalRigidMulti(x, y);
default:
return 0;
}
}
private double SingleCubicFractalFBM(double x, double y)
{
long seed = m_seed;
double sum = SingleCubic(seed, x, y);
double amp = 1;
long i = 0;
while(++i < m_octaves)
{
x *= m_lacunarity;
y *= m_lacunarity;
amp *= m_gain;
sum += SingleCubic(++seed, x, y) * amp;
}
return sum * m_fractalBounding;
}
private double SingleCubicFractalBillow(double x, double y)
{
long seed = m_seed;
double sum = Math.abs(SingleCubic(seed, x, y)) * 2 - 1;
double amp = 1;
long i = 0;
while(++i < m_octaves)
{
x *= m_lacunarity;
y *= m_lacunarity;
amp *= m_gain;
sum += (Math.abs(SingleCubic(++seed, x, y)) * 2 - 1) * amp;
}
return sum * m_fractalBounding;
}
private double SingleCubicFractalRigidMulti(double x, double y)
{
long seed = m_seed;
double sum = 1 - Math.abs(SingleCubic(seed, x, y));
double amp = 1;
long i = 0;
while(++i < m_octaves)
{
x *= m_lacunarity;
y *= m_lacunarity;
amp *= m_gain;
sum -= (1 - Math.abs(SingleCubic(++seed, x, y))) * amp;
}
return sum;
}
public double GetCubic(double x, double y)
{
x *= m_frequency;
y *= m_frequency;
return SingleCubic(0, x, y);
}
private final static double CUBIC_2D_BOUNDING = 1 / (double) (1.5 * 1.5);
private double SingleCubic(long seed, double x, double y)
{
long x1 = fastFloor(x);
long y1 = fastFloor(y);
long x0 = x1 - 1;
long y0 = y1 - 1;
long x2 = x1 + 1;
long y2 = y1 + 1;
long x3 = x1 + 2;
long y3 = y1 + 2;
double xs = x - (double) x1;
double ys = y - (double) y1;
return cubicLerp(cubicLerp(valCoord2D(seed, x0, y0), valCoord2D(seed, x1, y0), valCoord2D(seed, x2, y0), valCoord2D(seed, x3, y0), xs), cubicLerp(valCoord2D(seed, x0, y1), valCoord2D(seed, x1, y1), valCoord2D(seed, x2, y1), valCoord2D(seed, x3, y1), xs), cubicLerp(valCoord2D(seed, x0, y2), valCoord2D(seed, x1, y2), valCoord2D(seed, x2, y2), valCoord2D(seed, x3, y2), xs), cubicLerp(valCoord2D(seed, x0, y3), valCoord2D(seed, x1, y3), valCoord2D(seed, x2, y3), valCoord2D(seed, x3, y3), xs), ys) * CUBIC_2D_BOUNDING;
}
// Cellular Noise
public double GetCellular(double x, double y, double z)
{
x *= m_frequency;
y *= m_frequency;
z *= m_frequency;
switch(m_cellularReturnType)
{
case CellValue:
case NoiseLookup:
case Distance:
return SingleCellular(x, y, z);
default:
return SingleCellular2Edge(x, y, z);
}
}
private double SingleCellular(double x, double y, double z)
{
long xr = fastRound(x);
long yr = fastRound(y);
long zr = fastRound(z);
double distance = 999999;
long xc = 0, yc = 0, zc = 0;
switch(m_cellularDistanceFunction)
{
case Euclidean:
for(long xi = xr - 1; xi <= xr + 1; xi++)
{
for(long yi = yr - 1; yi <= yr + 1; yi++)
{
for(long zi = zr - 1; zi <= zr + 1; zi++)
{
Double3 vec = CELL_3D[(int) hash3D(m_seed, xi, yi, zi) & 255];
double vecX = xi - x + vec.x;
double vecY = yi - y + vec.y;
double vecZ = zi - z + vec.z;
double newDistance = vecX * vecX + vecY * vecY + vecZ * vecZ;
if(newDistance < distance)
{
distance = newDistance;
xc = xi;
yc = yi;
zc = zi;
}
}
}
}
break;
case Manhattan:
for(long xi = xr - 1; xi <= xr + 1; xi++)
{
for(long yi = yr - 1; yi <= yr + 1; yi++)
{
for(long zi = zr - 1; zi <= zr + 1; zi++)
{
Double3 vec = CELL_3D[(int) hash3D(m_seed, xi, yi, zi) & 255];
double vecX = xi - x + vec.x;
double vecY = yi - y + vec.y;
double vecZ = zi - z + vec.z;
double newDistance = Math.abs(vecX) + Math.abs(vecY) + Math.abs(vecZ);
if(newDistance < distance)
{
distance = newDistance;
xc = xi;
yc = yi;
zc = zi;
}
}
}
}
break;
case Natural:
for(long xi = xr - 1; xi <= xr + 1; xi++)
{
for(long yi = yr - 1; yi <= yr + 1; yi++)
{
for(long zi = zr - 1; zi <= zr + 1; zi++)
{
Double3 vec = CELL_3D[(int) hash3D(m_seed, xi, yi, zi) & 255];
double vecX = xi - x + vec.x;
double vecY = yi - y + vec.y;
double vecZ = zi - z + vec.z;
double newDistance = (Math.abs(vecX) + Math.abs(vecY) + Math.abs(vecZ)) + (vecX * vecX + vecY * vecY + vecZ * vecZ);
if(newDistance < distance)
{
distance = newDistance;
xc = xi;
yc = yi;
zc = zi;
}
}
}
}
break;
}
switch(m_cellularReturnType)
{
case CellValue:
return valCoord3D(0, xc, yc, zc);
case NoiseLookup:
Double3 vec = CELL_3D[(int) hash3D(m_seed, xc, yc, zc) & 255];
return m_cellularNoiseLookup.GetNoise(xc + vec.x, yc + vec.y, zc + vec.z);
case Distance:
return distance - 1;
default:
return 0;
}
}
private double SingleCellular2Edge(double x, double y, double z)
{
long xr = fastRound(x);
long yr = fastRound(y);
long zr = fastRound(z);
double distance = 999999;
double distance2 = 999999;
switch(m_cellularDistanceFunction)
{
case Euclidean:
for(long xi = xr - 1; xi <= xr + 1; xi++)
{
for(long yi = yr - 1; yi <= yr + 1; yi++)
{
for(long zi = zr - 1; zi <= zr + 1; zi++)
{
Double3 vec = CELL_3D[(int) hash3D(m_seed, xi, yi, zi) & 255];
double vecX = xi - x + vec.x;
double vecY = yi - y + vec.y;
double vecZ = zi - z + vec.z;
double newDistance = vecX * vecX + vecY * vecY + vecZ * vecZ;
distance2 = Math.max(Math.min(distance2, newDistance), distance);
distance = Math.min(distance, newDistance);
}
}
}
break;
case Manhattan:
for(long xi = xr - 1; xi <= xr + 1; xi++)
{
for(long yi = yr - 1; yi <= yr + 1; yi++)
{
for(long zi = zr - 1; zi <= zr + 1; zi++)
{
Double3 vec = CELL_3D[(int) hash3D(m_seed, xi, yi, zi) & 255];
double vecX = xi - x + vec.x;
double vecY = yi - y + vec.y;
double vecZ = zi - z + vec.z;
double newDistance = Math.abs(vecX) + Math.abs(vecY) + Math.abs(vecZ);
distance2 = Math.max(Math.min(distance2, newDistance), distance);
distance = Math.min(distance, newDistance);
}
}
}
break;
case Natural:
for(long xi = xr - 1; xi <= xr + 1; xi++)
{
for(long yi = yr - 1; yi <= yr + 1; yi++)
{
for(long zi = zr - 1; zi <= zr + 1; zi++)
{
Double3 vec = CELL_3D[(int) hash3D(m_seed, xi, yi, zi) & 255];
double vecX = xi - x + vec.x;
double vecY = yi - y + vec.y;
double vecZ = zi - z + vec.z;
double newDistance = (Math.abs(vecX) + Math.abs(vecY) + Math.abs(vecZ)) + (vecX * vecX + vecY * vecY + vecZ * vecZ);
distance2 = Math.max(Math.min(distance2, newDistance), distance);
distance = Math.min(distance, newDistance);
}
}
}
break;
default:
break;
}
switch(m_cellularReturnType)
{
case Distance2:
return distance2 - 1;
case Distance2Add:
return distance2 + distance - 1;
case Distance2Sub:
return distance2 - distance - 1;
case Distance2Mul:
return distance2 * distance - 1;
case Distance2Div:
return distance / distance2 - 1;
default:
return 0;
}
}
public double GetCellular(double x, double y)
{
x *= m_frequency;
y *= m_frequency;
switch(m_cellularReturnType)
{
case CellValue:
case NoiseLookup:
case Distance:
return SingleCellular(x, y);
default:
return SingleCellular2Edge(x, y);
}
}
private double SingleCellular(double x, double y)
{
long xr = fastRound(x);
long yr = fastRound(y);
double distance = 999999;
long xc = 0, yc = 0;
switch(m_cellularDistanceFunction)
{
default:
case Euclidean:
for(long xi = xr - 1; xi <= xr + 1; xi++)
{
for(long yi = yr - 1; yi <= yr + 1; yi++)
{
Double2 vec = CELL_2D[(int) hash2D(m_seed, xi, yi) & 255];
double vecX = xi - x + vec.x;
double vecY = yi - y + vec.y;
double newDistance = vecX * vecX + vecY * vecY;
if(newDistance < distance)
{
distance = newDistance;
xc = xi;
yc = yi;
}
}
}
break;
case Manhattan:
for(long xi = xr - 1; xi <= xr + 1; xi++)
{
for(long yi = yr - 1; yi <= yr + 1; yi++)
{
Double2 vec = CELL_2D[(int) hash2D(m_seed, xi, yi) & 255];
double vecX = xi - x + vec.x;
double vecY = yi - y + vec.y;
double newDistance = (Math.abs(vecX) + Math.abs(vecY));
if(newDistance < distance)
{
distance = newDistance;
xc = xi;
yc = yi;
}
}
}
break;
case Natural:
for(long xi = xr - 1; xi <= xr + 1; xi++)
{
for(long yi = yr - 1; yi <= yr + 1; yi++)
{
Double2 vec = CELL_2D[(int) hash2D(m_seed, xi, yi) & 255];
double vecX = xi - x + vec.x;
double vecY = yi - y + vec.y;
double newDistance = (Math.abs(vecX) + Math.abs(vecY)) + (vecX * vecX + vecY * vecY);
if(newDistance < distance)
{
distance = newDistance;
xc = xi;
yc = yi;
}
}
}
break;
}
switch(m_cellularReturnType)
{
case CellValue:
return valCoord2D(0, xc, yc);
case NoiseLookup:
Double2 vec = CELL_2D[(int) hash2D(m_seed, xc, yc) & 255];
return m_cellularNoiseLookup.GetNoise(xc + vec.x, yc + vec.y);
case Distance:
return distance - 1;
default:
return 0;
}
}
private double SingleCellular2Edge(double x, double y)
{
long xr = fastRound(x);
long yr = fastRound(y);
double distance = 999999;
double distance2 = 999999;
switch(m_cellularDistanceFunction)
{
default:
case Euclidean:
for(long xi = xr - 1; xi <= xr + 1; xi++)
{
for(long yi = yr - 1; yi <= yr + 1; yi++)
{
Double2 vec = CELL_2D[(int) hash2D(m_seed, xi, yi) & 255];
double vecX = xi - x + vec.x;
double vecY = yi - y + vec.y;
double newDistance = vecX * vecX + vecY * vecY;
distance2 = Math.max(Math.min(distance2, newDistance), distance);
distance = Math.min(distance, newDistance);
}
}
break;
case Manhattan:
for(long xi = xr - 1; xi <= xr + 1; xi++)
{
for(long yi = yr - 1; yi <= yr + 1; yi++)
{
Double2 vec = CELL_2D[(int) hash2D(m_seed, xi, yi) & 255];
double vecX = xi - x + vec.x;
double vecY = yi - y + vec.y;
double newDistance = Math.abs(vecX) + Math.abs(vecY);
distance2 = Math.max(Math.min(distance2, newDistance), distance);
distance = Math.min(distance, newDistance);
}
}
break;
case Natural:
for(long xi = xr - 1; xi <= xr + 1; xi++)
{
for(long yi = yr - 1; yi <= yr + 1; yi++)
{
Double2 vec = CELL_2D[(int) hash2D(m_seed, xi, yi) & 255];
double vecX = xi - x + vec.x;
double vecY = yi - y + vec.y;
double newDistance = (Math.abs(vecX) + Math.abs(vecY)) + (vecX * vecX + vecY * vecY);
distance2 = Math.max(Math.min(distance2, newDistance), distance);
distance = Math.min(distance, newDistance);
}
}
break;
}
switch(m_cellularReturnType)
{
case Distance2:
return distance2 - 1;
case Distance2Add:
return distance2 + distance - 1;
case Distance2Sub:
return distance2 - distance - 1;
case Distance2Mul:
return distance2 * distance - 1;
case Distance2Div:
return distance / distance2 - 1;
default:
return 0;
}
}
public void GradientPerturb(Vector3f v3)
{
SingleGradientPerturb(m_seed, m_gradientPerturbAmp, m_frequency, v3);
}
public void GradientPerturbFractal(Vector3f v3)
{
long seed = m_seed;
double amp = m_gradientPerturbAmp * m_fractalBounding;
double freq = m_frequency;
SingleGradientPerturb(seed, amp, m_frequency, v3);
for(long i = 1; i < m_octaves; i++)
{
freq *= m_lacunarity;
amp *= m_gain;
SingleGradientPerturb(++seed, amp, freq, v3);
}
}
private void SingleGradientPerturb(long seed, double perturbAmp, double frequency, Vector3f v3)
{
double xf = v3.x * frequency;
double yf = v3.y * frequency;
double zf = v3.z * frequency;
long x0 = fastFloor(xf);
long y0 = fastFloor(yf);
long z0 = fastFloor(zf);
long x1 = x0 + 1;
long y1 = y0 + 1;
long z1 = z0 + 1;
double xs, ys, zs;
switch(m_longerp)
{
default:
case Linear:
xs = xf - x0;
ys = yf - y0;
zs = zf - z0;
break;
case Hermite:
xs = longerpHermiteFunc(xf - x0);
ys = longerpHermiteFunc(yf - y0);
zs = longerpHermiteFunc(zf - z0);
break;
case Qulongic:
xs = longerpQulongicFunc(xf - x0);
ys = longerpQulongicFunc(yf - y0);
zs = longerpQulongicFunc(zf - z0);
break;
}
Double3 vec0 = CELL_3D[(int) hash3D(seed, x0, y0, z0) & 255];
Double3 vec1 = CELL_3D[(int) hash3D(seed, x1, y0, z0) & 255];
double lx0x = lerp(vec0.x, vec1.x, xs);
double ly0x = lerp(vec0.y, vec1.y, xs);
double lz0x = lerp(vec0.z, vec1.z, xs);
vec0 = CELL_3D[(int) hash3D(seed, x0, y1, z0) & 255];
vec1 = CELL_3D[(int) hash3D(seed, x1, y1, z0) & 255];
double lx1x = lerp(vec0.x, vec1.x, xs);
double ly1x = lerp(vec0.y, vec1.y, xs);
double lz1x = lerp(vec0.z, vec1.z, xs);
double lx0y = lerp(lx0x, lx1x, ys);
double ly0y = lerp(ly0x, ly1x, ys);
double lz0y = lerp(lz0x, lz1x, ys);
vec0 = CELL_3D[(int) hash3D(seed, x0, y0, z1) & 255];
vec1 = CELL_3D[(int) hash3D(seed, x1, y0, z1) & 255];
lx0x = lerp(vec0.x, vec1.x, xs);
ly0x = lerp(vec0.y, vec1.y, xs);
lz0x = lerp(vec0.z, vec1.z, xs);
vec0 = CELL_3D[(int) hash3D(seed, x0, y1, z1) & 255];
vec1 = CELL_3D[(int) hash3D(seed, x1, y1, z1) & 255];
lx1x = lerp(vec0.x, vec1.x, xs);
ly1x = lerp(vec0.y, vec1.y, xs);
lz1x = lerp(vec0.z, vec1.z, xs);
v3.x += lerp(lx0y, lerp(lx0x, lx1x, ys), zs) * perturbAmp;
v3.y += lerp(ly0y, lerp(ly0x, ly1x, ys), zs) * perturbAmp;
v3.z += lerp(lz0y, lerp(lz0x, lz1x, ys), zs) * perturbAmp;
}
public void GradientPerturb(Vector2f v2)
{
SingleGradientPerturb(m_seed, m_gradientPerturbAmp, m_frequency, v2);
}
public void GradientPerturbFractal(Vector2f v2)
{
long seed = m_seed;
double amp = m_gradientPerturbAmp * m_fractalBounding;
double freq = m_frequency;
SingleGradientPerturb(seed, amp, m_frequency, v2);
for(long i = 1; i < m_octaves; i++)
{
freq *= m_lacunarity;
amp *= m_gain;
SingleGradientPerturb(++seed, amp, freq, v2);
}
}
private void SingleGradientPerturb(long seed, double perturbAmp, double frequency, Vector2f v2)
{
double xf = v2.x * frequency;
double yf = v2.y * frequency;
long x0 = fastFloor(xf);
long y0 = fastFloor(yf);
long x1 = x0 + 1;
long y1 = y0 + 1;
double xs, ys;
switch(m_longerp)
{
default:
case Linear:
xs = xf - x0;
ys = yf - y0;
break;
case Hermite:
xs = longerpHermiteFunc(xf - x0);
ys = longerpHermiteFunc(yf - y0);
break;
case Qulongic:
xs = longerpQulongicFunc(xf - x0);
ys = longerpQulongicFunc(yf - y0);
break;
}
Double2 vec0 = CELL_2D[(int) hash2D(seed, x0, y0) & 255];
Double2 vec1 = CELL_2D[(int) hash2D(seed, x1, y0) & 255];
double lx0x = lerp(vec0.x, vec1.x, xs);
double ly0x = lerp(vec0.y, vec1.y, xs);
vec0 = CELL_2D[(int) hash2D(seed, x0, y1) & 255];
vec1 = CELL_2D[(int) hash2D(seed, x1, y1) & 255];
double lx1x = lerp(vec0.x, vec1.x, xs);
double ly1x = lerp(vec0.y, vec1.y, xs);
v2.x += lerp(lx0x, lx1x, ys) * perturbAmp;
v2.y += lerp(ly0x, ly1x, ys) * perturbAmp;
}
}