Curvalicious

Published March 14, 2007
Advertisement
After taking part in this thread, I started working on another extension module to libnoise to more conveniently handle the remapping of noise module output to an arbitrary curve function. I have a templated general curve class which implements a curve as a vector of points, templated on the type of the point. You can push points onto the curve, then call various interpolation functions with a parameter in the range [0,1]to sample the curve. Initially, I thought about just wrapping a curve of type double into a module wrapper, then sampling the curve using the source module's output value, but this would have added the extra overhead of a cubic or hermite interpolation of the curve for every module sample.

Instead, I decided to implement a module that encapsulates a lookup table instead, trading memory for (hopefully) increased performance, since noise generation is slow to start with. The module pre-allocates a 512 element lookup table ( the Resize() function can allocate a larger or smaller table) which is indexed to generate the output for the module. The module maintains a lower and upper bound set which determines the mapping into the table. Input values equal to lower map to element 0 in the table, input values equal to upper map to element SIZE-1 in the table. By setting the mapping to [-1,1] using SetMapping() (which, incidentally, is the default range) you can map the output of any of libnoise's perlin generator functions to values from the lookup table.

(And yeah, I'm aware of the existence of a curve-based module in libnoise already, but I wanted to support my own curve class which provides alternative interpolation methods such as spline interpolation, cosine approximation, linear, etc... The lookup table approach as well provides the ability to construct tables from non-continuous functions if desired, or even load color-scale-type graphs from a file to use as the mapping.

A set of helper functions are used to fill a module lookup table from a given curve. Alternatively, you can fill the lookup table with whatever random values you feel like; the helper functions are just there for convenience in populating a table.

The result is a module that takes 1 source module, and which samples that source module and remaps the output. Let's take a look at it in action.

Here is a sample curve(visualization of a min and max range of [-1,1]:


Here is a sample Perlin module output:


And here is the same module output, remapped to our curve:


The module and curve stuff have been folded into the current release build of my editor if you want to play around with it. The new features are:

* Added Lua binding to the CBasicCurved class, a double templated version of TBasicCurve, allowing scripts to instantiate curve objects.

CBasicCurved implements--
clear() -- Clear all points
setPoint(p) -- push the value p as a new curve point at the front of the curve
linearInterp(t) -- Sample the curve at t where t is in the range [0,1], using linear interpolation
cubicInterp(t) -- Sample the curve using more-correct (and slower) cubic interpolation
hermiteInterp(t,tension,bias) -- Sample the curve using a hermite spline method

Instances of CBasicCurved can be created in script with the function CreateBasicCurved().

* Add Lua binding for the ScaleTable libnoise extension module.

ScaleTable implements (on top of the underlying libnoise::module functionality inherited)--


SetMapping(lower,upper) -- Set the range on input to map into the lookup table
Resize(size) -- Set the size of the lookup table
GetSize() -- find out the size of the lookup table
SetTableEntry(which,p) -- Manually set an element in the lookup table

The ScaleTable module requires 1 source module in index 0 for proper function, and can be instanced using the ScaleTableModule() function.

* Add Lua binding for 3 helper functions to populate a ScaleTable module table


convertCurveToTableCubic(curve, st)
convertCurveToTableHermite(curve, st, tension, bias)
convertCurveToTableLinear(curve, st)


* Add a Lua binding for the function buildTerraceTable(st,numintervals) function, which constructs a stair-stepped ScaleTable module, useful for generating terraced terrain within a libnoise module chain.


Coming soon, I want to cleanup the docs, do some interface tweaking and improvements, and start fleshing out the UI stuff so that basic operations such as file save/load do not have to be done from the console. It's a work in progress.
Previous Entry GDC
Next Entry Shooping Whoop.
0 likes 1 comments

Comments

mrbastard
libnoise is great. I wanted to write a properly tiling voronoi generator for it, but never got round to it.
March 14, 2007 08:01 PM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement