fixed tree clumpyness setting
This commit is contained in:
+19
-16
@@ -11,7 +11,6 @@ import (
|
|||||||
|
|
||||||
"github.com/aquilax/go-perlin"
|
"github.com/aquilax/go-perlin"
|
||||||
"github.com/disintegration/imaging"
|
"github.com/disintegration/imaging"
|
||||||
"github.com/ojrac/opensimplex-go"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -220,18 +219,12 @@ func GenerateTrees(img *image.RGBA, waterMask, roadMask, buildingMask *PixelMask
|
|||||||
if targetTreePixels < 1 {
|
if targetTreePixels < 1 {
|
||||||
targetTreePixels = 1
|
targetTreePixels = 1
|
||||||
}
|
}
|
||||||
|
avgTreeSize := (minTreeSizePx + maxTreeSizePx) / 2.0
|
||||||
noise := opensimplex.New(seed)
|
avgTreeRadius := avgTreeSize / 2.0
|
||||||
treeNoiseMap := image.NewGray(image.Rect(0, 0, width, height))
|
avgTreeArea := math.Pi * avgTreeRadius * avgTreeRadius
|
||||||
treeNoiseZoom := 0.05
|
if avgTreeArea < 1 {
|
||||||
for y := 0; y < height; y++ {
|
avgTreeArea = 1
|
||||||
for x := 0; x < width; x++ {
|
|
||||||
val := noise.Eval2(float64(x)*treeNoiseZoom, float64(y)*treeNoiseZoom)
|
|
||||||
val = (val + 1) / 2
|
|
||||||
treeNoiseMap.SetGray(x, y, color.Gray{Y: uint8(val * 255)})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
threshold := uint8(255 * (1 - (treeCoverage / 100.0)))
|
|
||||||
|
|
||||||
if waterMask == nil {
|
if waterMask == nil {
|
||||||
waterMask = NewPixelMask(width, height)
|
waterMask = NewPixelMask(width, height)
|
||||||
@@ -244,13 +237,23 @@ func GenerateTrees(img *image.RGBA, waterMask, roadMask, buildingMask *PixelMask
|
|||||||
}
|
}
|
||||||
|
|
||||||
randSrc := rand.New(rand.NewSource(seed))
|
randSrc := rand.New(rand.NewSource(seed))
|
||||||
numClumpTrees := max(1, int(treeClumpiness))
|
// Clumpiness controls only distribution by changing seed node count:
|
||||||
|
// 0% -> many dispersed seeds, 100% -> one seed.
|
||||||
|
maxSeedNodes := int(float64(targetTreePixels) / avgTreeArea)
|
||||||
|
if maxSeedNodes < 1 {
|
||||||
|
maxSeedNodes = 1
|
||||||
|
}
|
||||||
|
clump := clamp(treeClumpiness, 0, 100) / 100.0
|
||||||
|
numClumpTrees := int(math.Round((1.0-clump)*float64(maxSeedNodes-1))) + 1
|
||||||
|
if numClumpTrees < 1 {
|
||||||
|
numClumpTrees = 1
|
||||||
|
}
|
||||||
|
|
||||||
initialPoints := make([]image.Point, 0, numClumpTrees)
|
initialPoints := make([]image.Point, 0, numClumpTrees)
|
||||||
for range numClumpTrees {
|
for range numClumpTrees {
|
||||||
for range 100 {
|
for range 100 {
|
||||||
p := image.Point{X: randSrc.Intn(width), Y: randSrc.Intn(height)}
|
p := image.Point{X: randSrc.Intn(width), Y: randSrc.Intn(height)}
|
||||||
if treeNoiseMap.GrayAt(p.X, p.Y).Y >= threshold && !waterMask.GetPoint(p) && !roadMask.GetPoint(p) && !buildingMask.GetPoint(p) {
|
if !waterMask.GetPoint(p) && !roadMask.GetPoint(p) && !buildingMask.GetPoint(p) {
|
||||||
initialPoints = append(initialPoints, p)
|
initialPoints = append(initialPoints, p)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -259,7 +262,7 @@ func GenerateTrees(img *image.RGBA, waterMask, roadMask, buildingMask *PixelMask
|
|||||||
if len(initialPoints) == 0 {
|
if len(initialPoints) == 0 {
|
||||||
for i := 0; i < 256; i++ {
|
for i := 0; i < 256; i++ {
|
||||||
p := image.Point{X: randSrc.Intn(width), Y: randSrc.Intn(height)}
|
p := image.Point{X: randSrc.Intn(width), Y: randSrc.Intn(height)}
|
||||||
if treeNoiseMap.GrayAt(p.X, p.Y).Y >= threshold && !waterMask.GetPoint(p) && !roadMask.GetPoint(p) && !buildingMask.GetPoint(p) {
|
if !waterMask.GetPoint(p) && !roadMask.GetPoint(p) && !buildingMask.GetPoint(p) {
|
||||||
initialPoints = append(initialPoints, p)
|
initialPoints = append(initialPoints, p)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -271,7 +274,7 @@ func GenerateTrees(img *image.RGBA, waterMask, roadMask, buildingMask *PixelMask
|
|||||||
|
|
||||||
minRadius := minTreeSizePx
|
minRadius := minTreeSizePx
|
||||||
allPoints := poissonDiscSampling(width, height, minRadius, 30, initialPoints, func(p image.Point) bool {
|
allPoints := poissonDiscSampling(width, height, minRadius, 30, initialPoints, func(p image.Point) bool {
|
||||||
return treeNoiseMap.GrayAt(p.X, p.Y).Y >= threshold && !waterMask.GetPoint(p) && !roadMask.GetPoint(p) && !buildingMask.GetPoint(p)
|
return !waterMask.GetPoint(p) && !roadMask.GetPoint(p) && !buildingMask.GetPoint(p)
|
||||||
}, seed)
|
}, seed)
|
||||||
treeMask := NewPixelMask(width, height)
|
treeMask := NewPixelMask(width, height)
|
||||||
if len(allPoints) == 0 {
|
if len(allPoints) == 0 {
|
||||||
|
|||||||
Reference in New Issue
Block a user