Skip to content

Commit

Permalink
Fix issues with terrainoptions api
Browse files Browse the repository at this point in the history
  • Loading branch information
gwaldron committed Oct 19, 2023
1 parent b27d02c commit f0e705c
Show file tree
Hide file tree
Showing 16 changed files with 166 additions and 235 deletions.
2 changes: 1 addition & 1 deletion src/applications/osgearth_magnify/osgearth_magnify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ int main(int argc, char** argv)
if (arguments.read("--sse"))
{
app._useLODScale = false;
MapNode::get(node)->getTerrainOptions().setRangeMode(osg::LOD::PIXEL_SIZE_ON_SCREEN);
MapNode::get(node)->getTerrainOptions().setLODMethod(TerrainLODMethod::SCREEN_SPACE);
}

// Add a UI to the main view:
Expand Down
2 changes: 1 addition & 1 deletion src/applications/osgearth_minimap/osgearth_minimap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ MapNode* makeMiniMapNode( )
map->addLayer(osm);

TerrainOptions terrainOptions;
terrainOptions.rangeMode() = osg::LOD::PIXEL_SIZE_ON_SCREEN;
terrainOptions.lodMethod() = TerrainLODMethod::SCREEN_SPACE;

MapNode::Options mapNodeOptions;
mapNodeOptions.terrain() = terrainOptions;
Expand Down
3 changes: 0 additions & 3 deletions src/osgEarth/FeatureModelGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2121,9 +2121,6 @@ FeatureModelGraph::traverse(osg::NodeVisitor& nv)
if (nv.getVisitorType() == nv.CULL_VISITOR)
{
OE_PROFILING_ZONE;
if (!_ownerName.empty())
OE_PROFILING_ZONE_TEXT(_ownerName);

osg::Group::traverse(nv);
}
else
Expand Down
2 changes: 1 addition & 1 deletion src/osgEarth/Geometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -820,7 +820,7 @@ Ring::getSignedArea2D() const
unsigned int n = size();
double area = 0.0;
int j = n - 1;
for (int i = 0; i < n; i++)
for (unsigned i = 0; i < n; i++)
{
area += ((*this)[j].x() + (*this)[i].x()) * ((*this)[j].y() - (*this)[i].y());
j = i;
Expand Down
64 changes: 36 additions & 28 deletions src/osgEarth/ImGui/TerrainGUI
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <osgEarth/LabelNode>
#include <osgEarth/SelectExtentTool>
#include <osgEarth/TerrainEngineNode>
#include <osgEarth/GLUtils>
#include <chrono>
#include <list>

Expand Down Expand Up @@ -94,53 +95,54 @@ namespace osgEarth
{
ImGuiLTable::Text("Resident Tiles", "%u", _mapNode->getTerrainEngine()->getNumResidentTiles());

auto terrain_options = _mapNode->getTerrainOptions();

static int max_max_lod = -1;
static unsigned u32_one = 1;
unsigned max_lod = terrain_options.getMaxLOD();
unsigned max_lod = options.getMaxLOD();
if (max_max_lod < 0) max_max_lod = max_lod;
if (ImGuiLTable::InputScalar("Max LOD", ImGuiDataType_U32, &max_lod, &u32_one, nullptr, "%u"))
{
max_lod = clamp(max_lod, 0u, (unsigned)max_max_lod);
terrain_options.setMaxLOD(max_lod);
options.setMaxLOD(max_lod);
}

osg::LOD::RangeMode mode = options.getRangeMode();
bool mode_b = (mode == osg::LOD::PIXEL_SIZE_ON_SCREEN);
if (ImGuiLTable::Checkbox("Screen space LOD", &mode_b))
TerrainLODMethod method = options.getLODMethod();
bool method_b = (method == TerrainLODMethod::SCREEN_SPACE);
if (ImGuiLTable::Checkbox("Screen space LOD", &method_b))
{
_mapNode->getTerrainOptions().setRangeMode(mode_b ? osg::LOD::PIXEL_SIZE_ON_SCREEN : osg::LOD::DISTANCE_FROM_EYE_POINT);
options.setLODMethod(method_b ? TerrainLODMethod::SCREEN_SPACE : TerrainLODMethod::CAMERA_DISTANCE);
}

if (_mapNode->getTerrainOptions().getRangeMode() == osg::LOD::PIXEL_SIZE_ON_SCREEN)
if (options.getLODMethod() == TerrainLODMethod::SCREEN_SPACE)
{
float tilePixelSize = _mapNode->getTerrainOptions().getTilePixelSize();
if (ImGuiLTable::SliderFloat("Effective pixel size:", &tilePixelSize, 64.0f, 1024.0f))
float tilePixelSize = options.getTilePixelSize();
if (ImGuiLTable::SliderFloat(" Pixels/tile:", &tilePixelSize, 64.0f, 1024.0f))
{
_mapNode->getTerrainOptions().setTilePixelSize(tilePixelSize);
options.setTilePixelSize(tilePixelSize);
}
}

unsigned maxTex = options.getMaxTextureSize();
const char* maxTexItems[] = { "16", "32", "64", "128", "256", "512", "1024", "2048", "4096", "8192", "16384" };
unsigned maxTexIndex = 0;
for (maxTexIndex = 0; maxTex > (unsigned)::atoi(maxTexItems[maxTexIndex]) && maxTexIndex < IM_ARRAYSIZE(maxTexItems) - 1; ++maxTexIndex);
if (ImGuiLTable::BeginCombo("Max tex size", maxTexItems[maxTexIndex])) {
for (int n = 0; n < IM_ARRAYSIZE(maxTexItems); n++) {
const bool is_selected = (maxTexIndex == n);
if (ImGui::Selectable(maxTexItems[n], is_selected)) {
maxTexIndex = n;
options.setMaxTextureSize(atoi(maxTexItems[maxTexIndex]));
_mapNode->getTerrainEngine()->dirtyTerrainOptions();
if (GLUtils::useNVGL())
{
unsigned maxTex = options.getMaxTextureSize();
const char* maxTexItems[] = { "16", "32", "64", "128", "256", "512", "1024", "2048", "4096", "8192", "16384" };
unsigned maxTexIndex = 0;
for (maxTexIndex = 0; maxTex > (unsigned)::atoi(maxTexItems[maxTexIndex]) && maxTexIndex < IM_ARRAYSIZE(maxTexItems) - 1; ++maxTexIndex);
if (ImGuiLTable::BeginCombo("Max tex size", maxTexItems[maxTexIndex])) {
for (int n = 0; n < IM_ARRAYSIZE(maxTexItems); n++) {
const bool is_selected = (maxTexIndex == n);
if (ImGui::Selectable(maxTexItems[n], is_selected)) {
maxTexIndex = n;
options.setMaxTextureSize(atoi(maxTexItems[maxTexIndex]));
_mapNode->getTerrainEngine()->dirtyTerrainOptions();
}
if (is_selected)
ImGui::SetItemDefaultFocus();
}
if (is_selected)
ImGui::SetItemDefaultFocus();
ImGuiLTable::EndCombo();
}
ImGuiLTable::EndCombo();
}

if (_mapNode->getTerrainOptions().getGPUTessellation())
if (options.getGPUTessellation())
{
ImGui::Separator();
ImGuiLTable::Section("Tessellation");
Expand All @@ -154,10 +156,16 @@ namespace osgEarth
options.setTessellationRange(range);
}

unsigned threads = options.getConcurrency();
if (ImGuiLTable::SliderInt("Load threads", (int*)&threads, 1, 16))
{
options.setConcurrency(threads);
_mapNode->getTerrainEngine()->dirtyTerrainOptions();
}

ImGuiLTable::End();
}

ImGui::Separator();
GeoPoint mp;
if (_mapNode->getGeoPointUnderMouse(view(ri), _x, _y, mp))
{
Expand Down
12 changes: 6 additions & 6 deletions src/osgEarth/ImageOverlay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -376,13 +376,13 @@ osg::Node* ImageOverlay::createNode()

osgEarth::Bounds bounds;

double minX = osg::minimum(_lowerLeft.x(), osg::minimum(_lowerRight.x(), osg::minimum(_upperLeft.x(), _upperRight.x())));
double minY = osg::minimum(_lowerLeft.y(), osg::minimum(_lowerRight.y(), osg::minimum(_upperLeft.y(), _upperRight.y())));
double maxX = osg::maximum(_lowerLeft.x(), osg::maximum(_lowerRight.x(), osg::maximum(_upperLeft.x(), _upperRight.x())));
double maxY = osg::maximum(_lowerLeft.y(), osg::maximum(_lowerRight.y(), osg::maximum(_upperLeft.y(), _upperRight.y())));
double minX = std::min(_lowerLeft.x(), std::min(_lowerRight.x(), std::min(_upperLeft.x(), _upperRight.x())));
double minY = std::min(_lowerLeft.y(), std::min(_lowerRight.y(), std::min(_upperLeft.y(), _upperRight.y())));
double maxX = std::max(_lowerLeft.x(), std::max(_lowerRight.x(), std::max(_upperLeft.x(), _upperRight.x())));
double maxY = std::max(_lowerLeft.y(), std::max(_lowerRight.y(), std::max(_upperLeft.y(), _upperRight.y())));

int numCols = osg::maximum(2, (int)((maxX - minX) / targetDegrees) + 1);
int numRows = osg::maximum(2, (int)((maxY - minY) / targetDegrees) + 1);
unsigned numCols = std::max(2, (int)((maxX - minX) / targetDegrees) + 1);
unsigned numRows = std::max(2, (int)((maxY - minY) / targetDegrees) + 1);

float dx = 1.0 / (float)(numCols - 1);
float dy = 1.0 / (float)(numRows - 1);
Expand Down
24 changes: 12 additions & 12 deletions src/osgEarth/SDF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,9 +393,9 @@ SDFGenerator::compute_nnf_on_cpu(osg::Image* buf) const

for (int L = n / 2; L >= 1; L /= 2)
{
for (unsigned int iterT = 0; iterT < buf->t(); ++iterT)
for (int iterT = 0; iterT < buf->t(); ++iterT)
{
for (unsigned int iterS = 0; iterS < buf->s(); ++iterS)
for (int iterS = 0; iterS < buf->s(); ++iterS)
{
readRGFloatPixel(imageData, imageWidth, imageHeight, pixel_points_to, iterS, iterT);

Expand Down Expand Up @@ -456,7 +456,7 @@ static void edt1d(const float* f, float* d, int* v, float* z, unsigned int n) {
v[0] = 0;
z[0] = -INF;
z[1] = INF;
for (int q = 1; q <= n - 1; ++q) {
for (int q = 1; q <= (int)(n - 1); ++q) {
float s = ((f[q] + q * q) - (f[v[k]] + v[k] * v[k])) / (2 * q - 2 * v[k]);
while (s <= z[k]) {
k--;
Expand All @@ -469,7 +469,7 @@ static void edt1d(const float* f, float* d, int* v, float* z, unsigned int n) {
}

k = 0;
for (int q = 0; q <= n - 1; ++q) {
for (int q = 0; q <= (int)(n - 1); ++q) {
while (z[k + 1] < q)
k++;
int r = v[k];
Expand All @@ -490,29 +490,29 @@ void edt2d(float* grid, unsigned int width, unsigned int height)
float* z = new float[maxLength + 1u];

// process columns
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
for (unsigned x = 0; x < width; ++x) {
for (unsigned y = 0; y < height; ++y) {
f[y] = grid[width * y + x];
}
// Do the distance transform.
edt1d(f, d, v, z, height);
// Copy d back into the grid
for (int y = 0; y < height; ++y) {
for (unsigned y = 0; y < height; ++y) {
grid[width * y + x] = d[y];
}
}

// process rows
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
for (unsigned y = 0; y < height; ++y) {
for (unsigned x = 0; x < width; ++x) {
f[x] = grid[width * y + x];
}

// Do the distance transform
edt1d(f, d, v, z, width);

// Copy d back into the grid
for (int x = 0; x < width; ++x) {
for (unsigned x = 0; x < width; ++x) {
grid[width * y + x] = d[x];
}
}
Expand Down Expand Up @@ -559,9 +559,9 @@ osg::Image* SDFGenerator::createDistanceField(const osg::Image* image, float min

ImageUtils::PixelWriter write(sdf.get());
write.assign(Color(1, 1, 1, 1));
for (int y = 0; y < height; ++y)
for (unsigned y = 0; y < height; ++y)
{
for (int x = 0; x < width; ++x)
for (unsigned x = 0; x < width; ++x)
{
// The distance computed is the square distance, so take the square root here to get the actual distance
float d = sqrt(grid[width * y + x]);
Expand Down
13 changes: 10 additions & 3 deletions src/osgEarth/TerrainEngineNode
Original file line number Diff line number Diff line change
Expand Up @@ -286,14 +286,18 @@ namespace osgEarth

void setComputeRangeCallback(ComputeRangeCallback* computeRangeCallback) override;

//! Return the top level node associated with the terrain.
osg::Node* getNode() override {
return this;
}

//! API for accessing or changing terrain options.
//! You should call dirtyTerrainOptions() after changing the options.
TerrainOptionsAPI getOptions() override {
return TerrainOptionsAPI(&_options);
return TerrainOptionsAPI(&_optionsConcrete);
}

//! Subclass may override this to do something when the terrain options change
virtual void dirtyTerrainOptions() { }

public:
Expand Down Expand Up @@ -333,7 +337,10 @@ namespace osgEarth
friend class TerrainEngineNodeFactory;

//! Assigns a map to render
virtual void setMap(const Map* map, const TerrainOptions& options);
void setMap(const Map* map, const TerrainOptions& options);

//! Subclass runs this after a call to setMap.
virtual void onSetMap() { }

// signals that a redraw is needed because something changed.
virtual void requestRedraw();
Expand Down Expand Up @@ -363,7 +370,7 @@ namespace osgEarth
osg::ref_ptr<Terrain> _terrainInterface;
unsigned _dirtyCount;
bool _updateScheduled;
TerrainOptions _options;
TerrainOptions _optionsConcrete;

typedef std::vector<osg::ref_ptr<TerrainEffect> > TerrainEffectVector;
TerrainEffectVector effects_;
Expand Down
23 changes: 13 additions & 10 deletions src/osgEarth/TerrainEngineNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,15 @@ TerrainEngineNode::getResources() const


TerrainEngineNode::TerrainEngineNode() :
_dirtyCount ( 0 ),
_requireElevationTextures( false ),
_requireNormalTextures ( false ),
_requireLandCoverTextures( false ),
_requireParentTextures ( false ),
_requireElevationBorder ( false ),
_requireFullDataAtFirstLOD( false ),
_updateScheduled( false ),
_createTileModelCallbacksMutex(OE_MUTEX_NAME)
_dirtyCount(0),
_requireElevationTextures(false),
_requireNormalTextures(false),
_requireLandCoverTextures(false),
_requireParentTextures(false),
_requireElevationBorder(false),
_requireFullDataAtFirstLOD(false),
_updateScheduled(false),
_createTileModelCallbacksMutex(OE_MUTEX_NAME)
{
// register for event traversals so we can properly reset the dirtyCount
ADJUST_EVENT_TRAV_COUNT(this, 1);
Expand Down Expand Up @@ -142,7 +142,7 @@ TerrainEngineNode::setMap(const Map* map, const TerrainOptions& options)
_map = map;

// store a const copy of the terrain options
_options = options;
_optionsConcrete = options;

// Create a terrain utility interface. This interface can be used
// to query the in-memory terrain graph, subscribe to tile events, etc.
Expand Down Expand Up @@ -174,6 +174,9 @@ TerrainEngineNode::setMap(const Map* map, const TerrainOptions& options)
this->setEllipsoidModel(nullptr);
}
}

// invoke the callback for a subclass to do its thing
onSetMap();
}

osg::BoundingSphere
Expand Down
15 changes: 11 additions & 4 deletions src/osgEarth/TerrainOptions
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@

namespace osgEarth
{
//! Method to use when determining when to switch terrain levels of detail.
enum class TerrainLODMethod
{
CAMERA_DISTANCE = osg::LOD::DISTANCE_FROM_EYE_POINT,
SCREEN_SPACE = osg::LOD::PIXEL_SIZE_ON_SCREEN
};

// Options structure for a terrain engine (internal)
class OSGEARTH_EXPORT TerrainOptions : public DriverConfigOptions
{
Expand All @@ -55,7 +62,7 @@ namespace osgEarth
OE_OPTION(unsigned, maxTilesToUnloadPerFrame);
OE_OPTION(unsigned, minResidentTiles);
OE_OPTION(bool, castShadows);
OE_OPTION(osg::LOD::RangeMode, rangeMode);
OE_OPTION(TerrainLODMethod, lodMethod);
OE_OPTION(float, tilePixelSize);
OE_OPTION(float, heightFieldSkirtRatio);
OE_OPTION(Color, color);
Expand Down Expand Up @@ -188,9 +195,9 @@ namespace osgEarth
const bool& getCastShadows() const;

//! Mode to use when calculating LOD switching distances.
//! Choices are DISTANCE_FROM_EYE_POINT (default) or PIXEL_SIZE_ON_SCREEN
void setRangeMode(const osg::LOD::RangeMode& value);
const osg::LOD::RangeMode& getRangeMode() const;
//! Choices are TerrainLODMode::CAMERA_DISTANCE (default) or TerrainLODMode::SCREEN_SPACE
void setLODMethod(const TerrainLODMethod& value);
const TerrainLODMethod& getLODMethod() const;

//! Size of the tile, in pixels, when using rangeMode = PIXEL_SIZE_ON_SCREEN
void setTilePixelSize(const float& value);
Expand Down
Loading

0 comments on commit f0e705c

Please sign in to comment.