Skip to content
caseymcc edited this page Jun 11, 2019 · 5 revisions

Welcome to the HastyNoise wiki!

Compiling:

CMake with Hunter

HastyNoise uses cmake and hunter (cmake package handler) for compilation. HastyNoise is also a package in hunter so if you are already using cmake/hunter adding HastyNoise to your application is as simple as adding the following to you CMakeLists.txt file and generating with cmake. HastyNoise will be downloaded and compiled then linked into you application.

hunter_add_package(HastyNoise)
find_package(HastyNoise CONFIG REQUIRED)

add_executable(hastynoise_test main.cpp)
target_link_libraries(hastynoise_test HastyNoise::hastyNoise)

CMake

If you would like to compile HastyNoise manually then you will need cmake 3.1+ then you can clone the repo and run cmake inside the repo directory

For Windows

cmake -H. -Bbuild -G "Visual Studio 14 2015 Win64" //for MSVS 2015
// or cmake -H. -Bbuild -G "Visual Studio 15 2017 Win64" //for MSVS 2017
cmake --build build

Most other platforms

cmake -H. -Bbuild
cmake --build build

Options

Additional cmake options that can be added to the cmake commandline via -D{option}

HN_BUILD_APP - (default:OFF) build test app for performance and confirmation testing
HN_PREVIEW_APP - (default:ON) builds preview app
HN_FAST_INVSQRT - (default:OFF) Uses fast but approximate invsqrt for non SIMD function calls

Example

//turn on test app and build (on windows using MSVS 2015)
cmake -H. -Bbuild -G "Visual Studio 15 2017 Win64" -DHN_BUILD_APP=ON
cmake --build build

API

HastyNoise is relatively easy to use.

Load Shared Libraries

The first thing you need to do is to load the shared libraries for each of the SIMD levels. This is done by calling loadSimd with the directory where the shared libs are stored. If the libraries are next the to exe this can be done like this:

HastyNoise::loadSimd("./");

Get SIMD Level

Next find out the highest level of performance that the CPU can handle, this is done by calling

size_t fastestSimd=HastyNoise::GetFastestSIMD();

This will check the CPU features and return the highest supported level of SIMD. Right now the function returns a size_t which has been cast from HastNoise::SIMDType, likely in the next version it will just return a HastNoise::SIMDType.

Create Noise Generator

Next you will need to create a noise generator; there are 2 functions for this either one that returns a raw pointer to a Noise object which you will then own and need to manually delete or one that will return a std::unique_ptr.

HastyNoise::NoiseSIMD *noise=HastyNoise::CreateNoise(seed, fastestSimd);

or

std::unique_ptr<HastyNoise::NoiseSIMD> noise=HastyNoise::CreateNoise(seed, fastestSimd);

The std::unique_ptr version is inline so there is no issue with cross boundary issues between the libs.

Set Noise Attributes

Once the generator has been created you can set all the settings on the class that you need using the following class members.

void SetSeed(int seed);
void SetNoiseType(NoiseType noiseType);
void SetFrequency(float frequency);

//Used only with NoiseType::ValueFractal, NoiseType::PerlinFractal, NoiseType::SimplexFractal, NoiseType::CubicFractal
void SetFractalType(FractalType fractalType);
void SetFractalOctaves(int octaves);
void SetFractalLacunarity(float lacunarity);
void SetFractalGain(float gain);

//Used only with NoiseType::Cellular
void SetCellularDistanceFunction(CellularDistance cellularDistance);
void SetCellularReturnType(CellularReturnType cellularReturnType)

Allocate Noise Buffer

Since HastyNoise is handling everything through SIMD the buffers that it is working on are expected to be aligned based on the level of SIMD used. The easiest way to handle this is to just call GetEmptySet.

inline FloatBuffer GetEmptySet(size_t size, size_t simdLevel);
inline FloatBuffer GetEmptySet(size_t xSize, size_t ySize, size_t zSize, size_t simdLevel);

This will return a FloatBuffer that is just a std::unique_ptr with a special deleter. FloatBuffer will allocate the proper aligned memory and the special deleter will handle deleting the aligned memory.

If you would like to handle the memory manually you can get the proper size by calling

size_t AlignedSize(size_t size, size_t simdLevel);

Generating Noise

After we have the generator and a buffer for the noise we can call

noise->FillSet(noiseBuffer.get(), 0, 0, 0, noiseSizeX, noiseSizeY, 1);

The first argument is a array of floats; followed by startX, startY, startZ, and then sizeX, sizeY, sizeZ. In general the API calls are expecting to generate 3D noise, however if you just want 2D put 1 in for sizeZ and 1D put 1 in for sizeY as well.

All of the above is wrapped up into the function

FloatBuffer GetNoiseSet(int xStart, int yStart, int zStart, int xSize, int ySize, int zSize, float scaleModifier);

however it will generate a new noise buffer each time it is called and will be a bottleneck for anything needing to generate often.

Vector Sets

The other way to get noise is to create a VectorSet and have it filled. The VectorSet allows you to arbitrarily chose the indexes that the noise will be created from. In the FillSet case it will fill linearly from start to start+size base on the scaleModifier. With vector set you can set the x,y,z points the generator will fill from.