51 lines
2.3 KiB
Go
51 lines
2.3 KiB
Go
package detail
|
|
|
|
// Classes is what the painted class asks of the detail passes, per cell, already blended.
|
|
//
|
|
// It exists because two classes can have the same uplift rate and the same erodibility - which is everything
|
|
// the geology grid knows about them - and still be completely different ground. A desert and a wet lowland
|
|
// are both "low, slowly rising"; what separates them is at two metres, in how much running water crosses
|
|
// them, how sharp their ledges stay and how much of them is dune.
|
|
//
|
|
// **Four fields rather than a class index and a lookup table**, which is what this was. The index is the
|
|
// right thing to carry - a class is a name, and a name is never interpolated - but the *numbers* it stands
|
|
// for are quantities, and quantities interpolate. Kept as a lookup, a desert meeting a lowland changed from
|
|
// seven metres of dune amplitude to two in the width of one cell, along a line the painter drew with a mouse,
|
|
// and it read exactly as what it was: a boundary in a picture rather than a change in the ground. Blended,
|
|
// the same boundary is a few hundred metres of one becoming the other, which is what the edge of a sand sea
|
|
// looks like from the ground.
|
|
//
|
|
// The blending happens where the fields are built (see planet.blendedClasses), because that is where the
|
|
// class raster and the tile's margin both are; by the time a pass reads one it is just a number per cell.
|
|
//
|
|
// Nil means every cell uses the pipeline's own numbers, which is what happens on a template whose legend
|
|
// overrides nothing.
|
|
type Classes struct {
|
|
Droplets []float32 // per cell: droplets a cell spawns
|
|
AmpLo []float32 // per cell: detail noise amplitude on flat ground
|
|
AmpHi []float32 // per cell: and on steep ground
|
|
Contrast []float32 // per cell: strata hardness contrast
|
|
}
|
|
|
|
// droplets, amp and contrast read a cell, falling back to the uniform value when there is no table.
|
|
func (c *Classes) droplets(i int, def float64) float64 {
|
|
if c == nil || c.Droplets == nil {
|
|
return def
|
|
}
|
|
return float64(c.Droplets[i])
|
|
}
|
|
|
|
func (c *Classes) amp(i int, defLo, defHi float64) (float64, float64) {
|
|
if c == nil || c.AmpLo == nil {
|
|
return defLo, defHi
|
|
}
|
|
return float64(c.AmpLo[i]), float64(c.AmpHi[i])
|
|
}
|
|
|
|
func (c *Classes) contrast(i int, def float64) float64 {
|
|
if c == nil || c.Contrast == nil {
|
|
return def
|
|
}
|
|
return float64(c.Contrast[i])
|
|
}
|