Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add height-query function to Tileset #783

Merged
merged 82 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
509deaa
update and comment intersection functions
Jan 2, 2024
35eb018
initial commit for height query class
Jan 2, 2024
6c97c53
Merge branch 'gltf-ray-intersect' into height-query
Jan 2, 2024
468595a
clang-format
Jan 2, 2024
4a767e9
add support for add-refine and cwt
Jan 3, 2024
89f5151
Merge branch 'gltf-ray-intersect' into height-query
csciguy8 May 6, 2024
8df6666
Merge branch 'gltf-ray-intersect' into height-query
csciguy8 May 16, 2024
530d4c2
Updates from intersectRayGltfModelParametric changes
csciguy8 May 16, 2024
98dbde9
Merge branch 'gltf-ray-intersect' into height-query
csciguy8 May 24, 2024
053021e
Merge branch 'gltf-ray-intersect' into height-query
csciguy8 May 28, 2024
565c255
Let ::getHeightsAtCoordinates return full Cartographic coordinates, n…
csciguy8 May 28, 2024
3f3944b
Merge branch 'gltf-ray-intersect' into height-query
csciguy8 May 31, 2024
dd6dece
Update to new hit results, and rework height return data to show if t…
csciguy8 May 31, 2024
2f86112
Merge branch 'gltf-ray-intersect' into height-query
csciguy8 Jun 13, 2024
29250be
Changes to support new IntersectResult
csciguy8 Jun 13, 2024
ce119c5
Fix closest hit logix
csciguy8 Jun 13, 2024
ec8f8ec
Modify return of _getHeightsAtCoordinates to support warnings
csciguy8 Jun 20, 2024
2668014
update from base branch
csciguy8 Jul 8, 2024
6bb57cf
Merge branch 'gltf-ray-intersect' into height-query
csciguy8 Jul 8, 2024
1076b4d
fix format
csciguy8 Jul 8, 2024
7e12ede
Merge branch 'gltf-ray-intersect' into height-query
csciguy8 Jul 10, 2024
82f56eb
Rework ::_processHeightRequests to split load work and intersect work
csciguy8 Jul 11, 2024
0d2a165
Don't add to load queue if tile already exists
csciguy8 Jul 11, 2024
5eba1aa
process request tile load all at once, rather than one at a time
csciguy8 Jul 11, 2024
fe35ba3
Fix release build warning
csciguy8 Jul 11, 2024
44b5ea3
fix build warning
csciguy8 Jul 12, 2024
c2b47f0
Reorg to change height finder to terrain query class
csciguy8 Jul 12, 2024
48d1b8b
move include path to fix build error
csciguy8 Jul 12, 2024
9690052
Merge branch 'gltf-ray-intersect' into height-query
csciguy8 Jul 24, 2024
07acc3a
Merge branch 'main' into height-query
csciguy8 Jul 29, 2024
73e213b
Fix compile error
csciguy8 Jul 29, 2024
5f6e9e4
process all height requests on every tick, rather than one at a time
csciguy8 Jul 31, 2024
57cf869
fix warning
csciguy8 Jul 31, 2024
7a1eae8
formatting
csciguy8 Jul 31, 2024
0af2f35
fix bug where height queries could unnecessarily wait unneeded tiles …
csciguy8 Jul 31, 2024
5a0e06e
add support for warnings that occur during tile traversal
csciguy8 Aug 1, 2024
cc8b03f
remove unnecessary check
csciguy8 Aug 1, 2024
7e16171
Merge branch 'main' into height-query
csciguy8 Aug 1, 2024
84493a7
Fix content bounding volume test
csciguy8 Aug 5, 2024
c0f5f18
Merge remote-tracking branch 'origin/main' into height-query
kring Aug 26, 2024
2accb6a
Incremental tree search in tryCompleteHeightRequest.
kring Aug 27, 2024
360154b
Remove use of variable from debug code.
kring Aug 27, 2024
68341f6
Fix an unknown bug in rayOBBParametric by rewriting it.
kring Aug 28, 2024
ef273ac
More performant rayOBBParametric.
kring Aug 28, 2024
06c47d8
Merge remote-tracking branch 'origin/main' into height-query
kring Sep 10, 2024
3be4524
We only need ContentLoaded for height queries.
kring Sep 10, 2024
1f77880
Use addTileToLoadQueue, no need to search existing first.
kring Sep 10, 2024
852710e
Round-robin scheduling of vis and height query loads.
kring Sep 10, 2024
f7450a2
Incremental traversal for additive-refined tiles, too.
kring Sep 10, 2024
5310d25
Remove unused lambda capture.
kring Sep 11, 2024
1f01f5a
Small tweaks and comments.
kring Sep 11, 2024
adea293
visitHeightRequests -> processHeightRequests
kring Sep 11, 2024
f270e4d
Allow height queries on a tileset that hasn't loaded at all yet.
kring Sep 11, 2024
fbb880b
Allow a null IPrepareRendererResources.
kring Sep 11, 2024
0a9e745
Add very basic height query tests.
kring Sep 11, 2024
dcc6c09
Don't do a full search if there are already additive candidates.
kring Sep 11, 2024
349bc22
Add external and implicit tileset tests.
kring Sep 11, 2024
b7a4244
Height queries against implicit tilesets.
kring Sep 11, 2024
d9ff8ac
Report a warning for unsupported extensions.
kring Sep 13, 2024
11d9f8e
Rename TerrainQuery to TilesetHeightQuery.
kring Sep 13, 2024
7c167ee
Minor reorg and documentation.
kring Sep 13, 2024
06d9e79
Move height query functionality out of Tileset.cpp.
kring Sep 13, 2024
51a5322
Cleanup and doc.
kring Sep 15, 2024
ca62417
Keep query tiles loaded until we're done with them.
kring Sep 16, 2024
5753669
Better marking of visited tiles.
kring Sep 16, 2024
3a37ba1
Fix "done loading" criteria.
kring Sep 16, 2024
bc0770a
Update CHANGES, small cleanup.
kring Sep 16, 2024
4850751
Reject height requests when tileset fails to load.
kring Sep 23, 2024
f7a75b1
Merge branch 'main' into height-query
j9liu Sep 25, 2024
7645a91
Remove unnecessary linebreak
j9liu Sep 25, 2024
23308ba
Doc tweaks
j9liu Sep 25, 2024
74acd1a
Additional tweak
j9liu Sep 26, 2024
85226ee
Update comment.
kring Sep 26, 2024
e401f59
Update comment.
kring Sep 26, 2024
352e609
Update doc.
kring Sep 26, 2024
e0323e9
Only create latent children if there are not any children yet.
kring Sep 26, 2024
63d6e4d
heightSampled -> sampleSuccess.
kring Sep 26, 2024
b48893a
tilesNeedingLoading -> tileLoadSet
kring Sep 26, 2024
87a4e68
Update doc.
kring Sep 27, 2024
ad18abf
Add sampleHeightMostDetailed test against a broken tileset.
kring Sep 27, 2024
fb38ac9
Fail height requests when Tileset is destroyed.
kring Sep 27, 2024
b56b1a2
Merge remote-tracking branch 'origin/main' into height-query
kring Sep 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions Cesium3DTilesSelection/include/Cesium3DTilesSelection/Tileset.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,17 @@

#include <rapidjson/fwd.h>

#include <list>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>

namespace Cesium3DTilesSelection {
class TilesetContentManager;
class TilesetMetadata;
class TerrainQuery;

/**
* @brief A <a
Expand Down Expand Up @@ -270,6 +273,19 @@ class CESIUM3DTILESSELECTION_API Tileset final {
*/
CesiumAsync::Future<const TilesetMetadata*> loadMetadata();

struct HeightResults {
struct CoordinateResult {
bool heightAvailable = false;
CesiumGeospatial::Cartographic coordinate = {-1, -1, -1};
};

std::vector<CoordinateResult> coordinateResults;
std::vector<std::string> warnings;
};

CesiumAsync::Future<HeightResults> getHeightsAtCoordinates(
const std::vector<CesiumGeospatial::Cartographic>& coordinates);

private:
/**
* @brief The result of traversing one branch of the tile hierarchy.
Expand Down Expand Up @@ -423,6 +439,11 @@ class CESIUM3DTILESSELECTION_API Tileset final {
double tilePriority,
bool queuedForLoad);

struct HeightRequest {
std::vector<TerrainQuery> queries;
CesiumAsync::Promise<Tileset::HeightResults> promise;
};

void _processWorkerThreadLoadQueue();
void _processMainThreadLoadQueue();

Expand Down Expand Up @@ -509,11 +530,19 @@ class CESIUM3DTILESSELECTION_API Tileset final {
CesiumUtility::IntrusivePointer<TilesetContentManager>
_pTilesetContentManager;

std::list<HeightRequest> _heightRequests;

void addTileToLoadQueue(
Tile& tile,
TileLoadPriorityGroup priorityGroup,
double priority);

void visitHeightRequests();

bool tryCompleteHeightRequest(
HeightRequest& request,
std::set<Tile*>& tilesNeedingLoading);

static TraversalDetails createTraversalDetailsForSingleTile(
const FrameState& frameState,
const Tile& tile,
Expand Down
138 changes: 138 additions & 0 deletions Cesium3DTilesSelection/src/TerrainQuery.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
#include "TerrainQuery.h"

#include "TileUtilities.h"
#include "TilesetContentManager.h"

#include <CesiumGeometry/IntersectionTests.h>
#include <CesiumGeospatial/GlobeRectangle.h>
#include <CesiumGltfContent/GltfUtilities.h>

using namespace Cesium3DTilesSelection;
using namespace CesiumGeospatial;
using namespace CesiumGeometry;
using namespace CesiumUtility;
using namespace CesiumAsync;

namespace {
bool boundingVolumeContainsCoordinate(
const BoundingVolume& boundingVolume,
const Ray& ray,
const Cartographic& coordinate) {
struct Operation {
const Ray& ray;
const Cartographic& coordinate;

bool operator()(const OrientedBoundingBox& boundingBox) noexcept {
std::optional<double> t =
IntersectionTests::rayOBBParametric(ray, boundingBox);
return t && t.value() >= 0;
}

bool operator()(const BoundingRegion& boundingRegion) noexcept {
return boundingRegion.getRectangle().contains(coordinate);
}

bool operator()(const BoundingSphere& boundingSphere) noexcept {
std::optional<double> t =
IntersectionTests::raySphereParametric(ray, boundingSphere);
return t && t.value() >= 0;
}

bool operator()(
const BoundingRegionWithLooseFittingHeights& boundingRegion) noexcept {
return boundingRegion.getBoundingRegion().getRectangle().contains(
coordinate);
}

bool operator()(const S2CellBoundingVolume& s2Cell) noexcept {
return s2Cell.computeBoundingRegion().getRectangle().contains(coordinate);
}
};

return std::visit(Operation{ray, coordinate}, boundingVolume);
}

} // namespace

void TerrainQuery::intersectVisibleTile(Tile* pTile) {
TileRenderContent* pRenderContent = pTile->getContent().getRenderContent();
if (!pRenderContent)
return;

auto gltfIntersectResult =
CesiumGltfContent::GltfUtilities::intersectRayGltfModel(
this->ray,
pRenderContent->getModel(),
true,
pTile->getTransform());

if (!gltfIntersectResult.hit.has_value())
return;

// Set ray info to this hit if closer, or the first hit
if (!this->intersectResult.hit.has_value()) {
this->intersectResult = std::move(gltfIntersectResult);
} else {
double prevDistSq = this->intersectResult.hit->rayToWorldPointDistanceSq;
double thisDistSq = intersectResult.hit->rayToWorldPointDistanceSq;
if (thisDistSq < prevDistSq)
this->intersectResult = std::move(gltfIntersectResult);
}
}

void TerrainQuery::findCandidateTiles(
Tile* pTile,
std::vector<std::string>& warnings) {

// If tile failed to load, this means we can't complete the intersection
if (pTile->getState() == TileLoadState::Failed) {
warnings.push_back("Tile load failed during query. Ignoring.");
return;
}

auto& contentBoundingVolume = pTile->getContentBoundingVolume();

if (pTile->getChildren().empty()) {
// This is a leaf node, it's a candidate

// If optional content bounding volume exists, test against it
if (contentBoundingVolume) {
if (boundingVolumeContainsCoordinate(
*contentBoundingVolume,
this->ray,
this->inputCoordinate))
candidateTiles.push_back(pTile);
} else {
candidateTiles.push_back(pTile);
}
} else {
// We have children

// If additive refinement, add parent to the list with children
if (pTile->getRefine() == TileRefine::Add) {
// If optional content bounding volume exists, test against it
if (contentBoundingVolume) {
if (boundingVolumeContainsCoordinate(
*contentBoundingVolume,
this->ray,
this->inputCoordinate))
candidateTiles.push_back(pTile);
} else {
candidateTiles.push_back(pTile);
}
}

// Traverse children
for (Tile& child : pTile->getChildren()) {
// if bounding volume doesn't intersect this ray, we can skip it
if (!boundingVolumeContainsCoordinate(
child.getBoundingVolume(),
this->ray,
this->inputCoordinate))
continue;

// Child is a candidate, traverse it and its children
findCandidateTiles(&child, warnings);
}
}
}
25 changes: 25 additions & 0 deletions Cesium3DTilesSelection/src/TerrainQuery.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

#include <Cesium3DTilesSelection/Tileset.h>
#include <CesiumGeometry/Ray.h>
#include <CesiumGeospatial/Cartographic.h>
#include <CesiumGltfContent/GltfUtilities.h>

#include <set>
#include <vector>

namespace Cesium3DTilesSelection {

class TerrainQuery {
public:
CesiumGeospatial::Cartographic inputCoordinate;
CesiumGeometry::Ray ray;
CesiumGltfContent::GltfUtilities::IntersectResult intersectResult = {};
std::vector<Tile*> candidateTiles = {};

void intersectVisibleTile(Tile* pTile);

void findCandidateTiles(Tile* pTile, std::vector<std::string>& warnings);
};

} // namespace Cesium3DTilesSelection
Loading
Loading