Skip to content

Commit

Permalink
Veg: add density parameter and update gui.
Browse files Browse the repository at this point in the history
  • Loading branch information
gwaldron committed Mar 8, 2022
1 parent df47bb6 commit 0f589e5
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 47 deletions.
26 changes: 15 additions & 11 deletions src/osgEarthProcedural/ImGui/VegetationLayerGUI
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,9 @@ namespace osgEarth {
if (ImGui::SliderFloat("Far", &sse_scales[1], 0.5f, 2.0f))
_veglayer->setSSEScales(sse_scales);

if (ImGui::Button("Regenerate"))
_veglayer->dirty();
ImGui::Separator();
ImGui::TextColored(ImVec4(1, 1, 0, 1), "Generator:");

ImGui::TextColored(ImVec4(1, 1, 0, 1), "Groups:");
ImGui::Indent();
for (int i = 0; i < NUM_ASSET_GROUPS; ++i)
{
ImGui::PushID(i);
Expand All @@ -91,17 +89,23 @@ namespace osgEarth {
AssetGroup::name(type).c_str(),
&_veglayer->options().group(type).enabled().mutable_value());

if (ImGui::SliderFloat(
"Range",
ImGui::SliderFloat(
"Max range",
&_veglayer->options().group(type).maxRange().mutable_value(),
0.0f, _maxMaxRanges[i]))
{
_veglayer->setMaxRange(type, _veglayer->options().group(type).maxRange().get());
}
0.0f, _maxMaxRanges[i]);

ImGui::SliderFloat(
"Density",
&_veglayer->options().group(type).density().mutable_value(),
0.0f, 1.0f);

ImGui::PopID();
}
ImGui::Unindent();

if (ImGui::Button("Regenerate Now"))
_veglayer->dirty();

ImGui::Separator();

if (ImGui::CollapsingHeader("All Biomes"))
{
Expand Down
10 changes: 3 additions & 7 deletions src/osgEarthProcedural/VegetationLayer
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,15 @@ namespace osgEarth { namespace Procedural
META_LayerOptions(osgEarth, Options, PatchLayer::Options);
OE_OPTION_LAYER(ImageLayer, colorLayer);
OE_OPTION_LAYER(BiomeLayer, biomeLayer);
OE_OPTION(float, colorMinSaturation);
OE_OPTION(bool, alphaToCoverage);
OE_OPTION(float, maxSSE);

struct OSGEARTHPROCEDURAL_EXPORT Group
{
OE_OPTION(bool, enabled);
OE_OPTION(Distance, spacing);
OE_OPTION(float, maxRange);
OE_OPTION(unsigned, lod);
OE_OPTION(unsigned, count);
OE_OPTION(float, maxRange);
OE_OPTION(float, density);
OE_OPTION(bool, castShadows);
OE_OPTION(float, maxAlpha);

// internal
osg::ref_ptr<osg::StateSet> _drawStateSet;
Expand Down Expand Up @@ -99,7 +95,7 @@ namespace osgEarth { namespace Procedural
ImageLayer* getColorLayer() const;

//! LOD at which to draw ground cover
bool hasGroupAtLOD(unsigned lod) const;
bool hasEnabledGroupAtLOD(unsigned lod) const;
AssetGroup::Type getGroupAtLOD(unsigned lod) const;
unsigned getGroupLOD(AssetGroup::Type) const;

Expand Down
68 changes: 39 additions & 29 deletions src/osgEarthProcedural/VegetationLayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ VegetationLayer::Options::getConfig() const
colorLayer().set(conf, "color_layer");
biomeLayer().set(conf, "biomes_layer");

conf.set("color_min_saturation", colorMinSaturation());
conf.set("alpha_to_coverage", alphaToCoverage());

//TODO: groups
Expand All @@ -113,38 +112,31 @@ VegetationLayer::Options::fromConfig(const Config& conf)
{
// defaults:
alphaToCoverage().setDefault(true);
maxSSE().setDefault(150.0f);

colorLayer().get(conf, "color_layer");
biomeLayer().get(conf, "biomes_layer");

conf.get("color_min_saturation", colorMinSaturation());
conf.get("alpha_to_coverage", alphaToCoverage());
conf.get("max_sse", maxSSE());

// defaults for groups:
groups().resize(NUM_ASSET_GROUPS);

if (AssetGroup::TREES < NUM_ASSET_GROUPS)
{
groups()[AssetGroup::TREES].enabled() = true;
groups()[AssetGroup::TREES].castShadows() = true;
groups()[AssetGroup::TREES].maxRange() = 4000.0f;
groups()[AssetGroup::TREES].lod() = 14;
groups()[AssetGroup::TREES].count() = 4096;
groups()[AssetGroup::TREES].spacing() = Distance(15.0f, Units::METERS);
groups()[AssetGroup::TREES].maxAlpha() = 0.15f;
groups()[AssetGroup::TREES].lod().setDefault(14);
groups()[AssetGroup::TREES].enabled().setDefault(true);
groups()[AssetGroup::TREES].castShadows().setDefault(true);
groups()[AssetGroup::TREES].maxRange().setDefault(4000.0f);
groups()[AssetGroup::TREES].density().setDefault(0.5f);
}

if (AssetGroup::UNDERGROWTH < NUM_ASSET_GROUPS)
{
groups()[AssetGroup::UNDERGROWTH].enabled() = true;
groups()[AssetGroup::UNDERGROWTH].castShadows() = false;
groups()[AssetGroup::UNDERGROWTH].maxRange() = 75.0f;
groups()[AssetGroup::UNDERGROWTH].lod() = 19;
groups()[AssetGroup::UNDERGROWTH].count() = 4096;
groups()[AssetGroup::UNDERGROWTH].spacing() = Distance(1.0f, Units::METERS);
groups()[AssetGroup::UNDERGROWTH].maxAlpha() = 0.75f;
groups()[AssetGroup::UNDERGROWTH].lod().setDefault(19);
groups()[AssetGroup::UNDERGROWTH].enabled().setDefault(true);
groups()[AssetGroup::UNDERGROWTH].castShadows().setDefault(false);
groups()[AssetGroup::UNDERGROWTH].maxRange().setDefault(75.0f);
groups()[AssetGroup::UNDERGROWTH].density().setDefault(1.0f);
}

ConfigSet groups_c = conf.child("groups").children();
Expand All @@ -162,20 +154,20 @@ VegetationLayer::Options::fromConfig(const Config& conf)
{
Group& group = groups()[g];
group_c.get("enabled", group.enabled());
group_c.get("spacing", group.spacing());
group_c.get("max_range", group.maxRange());
group_c.get("density", group.density());
group_c.get("lod", group.lod());
group_c.get("count", group.count());
group_c.get("cast_shadows", group.castShadows());
group_c.get("max_alpha", group.maxAlpha());
}
}
}

//........................................................................

bool
VegetationLayer::LayerAcceptor::acceptLayer(osg::NodeVisitor& nv, const osg::Camera* camera) const
VegetationLayer::LayerAcceptor::acceptLayer(
osg::NodeVisitor& nv,
const osg::Camera* camera) const
{
// if this is a shadow camera and the layer is configured to cast shadows, accept it.
if (CameraUtils::isShadowCamera(camera))
Expand All @@ -196,7 +188,7 @@ VegetationLayer::LayerAcceptor::acceptLayer(osg::NodeVisitor& nv, const osg::Cam
bool
VegetationLayer::LayerAcceptor::acceptKey(const TileKey& key) const
{
return _layer->hasGroupAtLOD(key.getLOD());
return _layer->hasEnabledGroupAtLOD(key.getLOD());
}

//........................................................................
Expand Down Expand Up @@ -382,12 +374,15 @@ VegetationLayer::getCastShadows() const
}

bool
VegetationLayer::hasGroupAtLOD(unsigned lod) const
VegetationLayer::hasEnabledGroupAtLOD(unsigned lod) const
{
for (int i = 0; i < NUM_ASSET_GROUPS; ++i)
{
if (options().groups()[i].lod() == lod)
if (options().groups()[i].lod() == lod &&
options().groups()[i].enabled() == true)
{
return true;
}
}
return false;
}
Expand Down Expand Up @@ -1088,8 +1083,6 @@ VegetationLayer::getAssetPlacements(
ImageUtils::PixelReader readNoise(_noiseTex->getImage(0));
readNoise.setSampleAsRepeatingTexture(true);

unsigned max_instances = options().group(group).count().get();

struct CollisionData
{
double x, y, radius;
Expand All @@ -1100,6 +1093,17 @@ VegetationLayer::getAssetPlacements(
std::minstd_rand0 gen(key.hash());
std::uniform_real_distribution<float> rand_float(0.0f, 1.0f);

unsigned max_instances = 4096;

bool allow_overlap = (group == AssetGroup::UNDERGROWTH);

float packing_density = options().group(group).density().get();

if (allow_overlap)
{
max_instances = (unsigned)((float)max_instances * packing_density);
}

// reserve some memory, maybe more than we need
result.reserve(max_instances);

Expand Down Expand Up @@ -1225,7 +1229,7 @@ VegetationLayer::getAssetPlacements(
}

// allow overlap for "billboard" models (i.e. grasses).
bool allow_overlap = isGrass;
//bool allow_overlap = isGrass;

// apply instance-specific density adjustment:
density *= instance.coverage();
Expand Down Expand Up @@ -1272,7 +1276,8 @@ VegetationLayer::getAssetPlacements(

// adjust collision radius based on density.
// i.e., denser areas allow vegetation to be closer.
double search_radius = mix(radius*3.0f, radius*0.5f, density);
double density_mix = density * packing_density;
double search_radius = mix(radius*3.0f, radius*0.2f, density_mix);
double search_radius_2 = search_radius * search_radius;

bool collision = false;
Expand Down Expand Up @@ -1413,6 +1418,11 @@ VegetationLayer::cull(
AssetGroup::Type group = getGroupAtLOD(entry->getKey().getLOD());
OE_HARD_ASSERT(group != AssetGroup::UNDEFINED);

if (options().group(group).enabled() == false)
{
continue;
}

if (CameraUtils::isShadowCamera(cv->getCurrentCamera()) &&
options().group(group).castShadows() == false)
{
Expand Down

0 comments on commit 0f589e5

Please sign in to comment.