Skip to content

Commit

Permalink
Merge pull request #109 from CesiumGS/cmpt
Browse files Browse the repository at this point in the history
Full support for multiple-b3dm-in-cmpt tiles, and some other fixes
  • Loading branch information
baothientran authored Feb 2, 2021
2 parents c3d35cf + 13ce898 commit 82361b3
Show file tree
Hide file tree
Showing 14 changed files with 248 additions and 73 deletions.
1 change: 1 addition & 0 deletions Cesium3DTiles/include/Cesium3DTiles/RasterMappedTo3DTile.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ namespace Cesium3DTiles {
glm::dvec2 _translation;
glm::dvec2 _scale;
AttachmentState _state;
bool _originalFailed;
};

}
7 changes: 3 additions & 4 deletions Cesium3DTiles/include/Cesium3DTiles/TileID.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,15 @@ namespace Cesium3DTiles {
* * A {@link CesiumGeometry::OctreeTileID}: This is an implicit
* tile in the octree. The URL of the tile's content is formed
* by instantiating the context's template URL with this ID.
* * A {@link CesiumGeometry::QuadtreeChild}: This tile doesn't
* * A {@link CesiumGeometry::UpsampledQuadtreeNode}: This tile doesn't
* have any content, but content for it can be created by subdividing
* the parent tile's content into four equal tiles and taking the
* quadrant identified.
* the parent tile's content.
*/
typedef std::variant<
std::string,
CesiumGeometry::QuadtreeTileID,
CesiumGeometry::OctreeTileID,
CesiumGeometry::QuadtreeChild
CesiumGeometry::UpsampledQuadtreeNode
> TileID;

}
18 changes: 15 additions & 3 deletions Cesium3DTiles/src/CompositeContent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,21 @@ namespace Cesium3DTiles {
} else if (innerTiles.size() == 1) {
return std::move(innerTiles[0]);
} else {
// TODO: combine all inner tiles into one glTF instead of return only the first.
SPDLOG_LOGGER_WARN(pLogger, "Composite tile contains multiple loadable inner tiles. Due to a temporary limitation, only the first will be used.");
return std::move(innerTiles[0]);
std::unique_ptr<TileContentLoadResult> pResult = std::move(innerTiles[0]);

for (size_t i = 1; i < innerTiles.size(); ++i) {
if (!innerTiles[i]->model) {
continue;
}

if (pResult->model) {
pResult->model.value().merge(std::move(innerTiles[i]->model.value()));
} else {
pResult->model = std::move(innerTiles[i]->model);
}
}

return pResult;
}
}

Expand Down
4 changes: 4 additions & 0 deletions Cesium3DTiles/src/GltfContent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ namespace Cesium3DTiles {

pResult->model = std::move(loadedModel.model);

if (pResult->model) {
pResult->model.value().extras["Cesium3DTiles_TileUrl"] = url;
}

return pResult;
}

Expand Down
4 changes: 4 additions & 0 deletions Cesium3DTiles/src/QuantizedMeshContent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -948,6 +948,10 @@ namespace Cesium3DTiles {

pResult->updatedBoundingVolume = BoundingRegion(rectangle, minimumHeight, maximumHeight);

if (pResult->model) {
pResult->model.value().extras["Cesium3DTiles_TileUrl"] = url;
}

return pResult;
}

Expand Down
13 changes: 9 additions & 4 deletions Cesium3DTiles/src/RasterMappedTo3DTile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,24 @@ namespace Cesium3DTiles {
_textureCoordinateRectangle(textureCoordinateRectangle),
_translation(0.0, 0.0),
_scale(1.0, 1.0),
_state(AttachmentState::Unattached)
_state(AttachmentState::Unattached),
_originalFailed(false)
{
}

RasterMappedTo3DTile::MoreDetailAvailable RasterMappedTo3DTile::update(Tile& tile) {
if (this->getState() == AttachmentState::Attached) {
return this->_pReadyTile && this->_pReadyTile->getID().level < this->_pReadyTile->getOverlay().getTileProvider()->getMaximumLevel()
return !this->_originalFailed && this->_pReadyTile && this->_pReadyTile->getID().level < this->_pReadyTile->getOverlay().getTileProvider()->getMaximumLevel()
? MoreDetailAvailable::Yes
: MoreDetailAvailable::No;
}

// If the loading tile has failed, try its parent.
while (this->_pLoadingTile && this->_pLoadingTile->getState() == RasterOverlayTile::LoadState::Failed && this->_pLoadingTile->getID().level > 0) {
// Note when our original tile fails to load so that we don't report more data available.
// This means - by design - we won't refine past a failed tile.
this->_originalFailed = true;

CesiumGeometry::QuadtreeTileID thisID = this->_pLoadingTile->getID();
CesiumGeometry::QuadtreeTileID parentID(thisID.level - 1, thisID.x >> 1, thisID.y >> 1);
this->_pLoadingTile = this->_pLoadingTile->getOverlay().getTileProvider()->getTile(parentID);
Expand All @@ -52,7 +57,7 @@ namespace Cesium3DTiles {
this->_state = AttachmentState::Unattached;
}

// Mark the loading tile read.
// Mark the loading tile ready.
this->_pReadyTile = this->_pLoadingTile;
this->_pLoadingTile = nullptr;

Expand Down Expand Up @@ -119,7 +124,7 @@ namespace Cesium3DTiles {
if (this->_pLoadingTile) {
return MoreDetailAvailable::Unknown;
} else {
return this->_pReadyTile && this->_pReadyTile->getID().level < this->_pReadyTile->getOverlay().getTileProvider()->getMaximumLevel()
return !this->_originalFailed && this->_pReadyTile && this->_pReadyTile->getID().level < this->_pReadyTile->getOverlay().getTileProvider()->getMaximumLevel()
? MoreDetailAvailable::Yes
: MoreDetailAvailable::No;
}
Expand Down
50 changes: 37 additions & 13 deletions Cesium3DTiles/src/Tile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ namespace Cesium3DTiles {
if (!maybeRequestFuture) {
// There is no content to load. But we may need to upsample.

const QuadtreeChild* pSubdivided = std::get_if<QuadtreeChild>(&this->getTileID());
const UpsampledQuadtreeNode* pSubdivided = std::get_if<UpsampledQuadtreeNode>(&this->getTileID());
if (pSubdivided) {
// We can't upsample this tile until its parent tile is done loading.
if (this->getParent() && this->getParent()->getState() == LoadState::Done) {
Expand Down Expand Up @@ -316,7 +316,7 @@ namespace Cesium3DTiles {
for (const Tile& child : this->getChildren()) {
if (
child.getState() == Tile::LoadState::ContentLoading &&
std::get_if<CesiumGeometry::QuadtreeChild>(&child.getTileID()) != nullptr
std::get_if<CesiumGeometry::UpsampledQuadtreeNode>(&child.getTileID()) != nullptr
) {
return false;
}
Expand Down Expand Up @@ -385,6 +385,32 @@ namespace Cesium3DTiles {
return;
}

// TODO: support upsampling non-quadtrees.
const QuadtreeTileID* pParentTileID = std::get_if<QuadtreeTileID>(&parent.getTileID());
if (!pParentTileID) {
const UpsampledQuadtreeNode* pUpsampledID = std::get_if<UpsampledQuadtreeNode>(&parent.getTileID());
if (pUpsampledID) {
pParentTileID = &pUpsampledID->tileID;
}
}

if (!pParentTileID) {
return;
}

// TODO: support upsampling non-implicit tiles.
if (!parent.getContext()->implicitContext) {
return;
}

QuadtreeTileID swID(pParentTileID->level + 1, pParentTileID->x * 2, pParentTileID->y * 2);
QuadtreeTileID seID(swID.level, swID.x + 1, swID.y);
QuadtreeTileID nwID(swID.level, swID.x, swID.y + 1);
QuadtreeTileID neID(swID.level, swID.x + 1, swID.y + 1);

QuadtreeTilingScheme& tilingScheme = parent.getContext()->implicitContext.value().tilingScheme;
Projection& projection = parent.getContext()->implicitContext.value().projection;

parent.createChildTiles(4);

gsl::span<Tile> children = parent.getChildren();
Expand All @@ -409,33 +435,31 @@ namespace Cesium3DTiles {
nw.setParent(&parent);
ne.setParent(&parent);

sw.setTileID(QuadtreeChild::LowerLeft);
se.setTileID(QuadtreeChild::LowerRight);
nw.setTileID(QuadtreeChild::UpperLeft);
ne.setTileID(QuadtreeChild::UpperRight);
sw.setTileID(UpsampledQuadtreeNode { swID });
se.setTileID(UpsampledQuadtreeNode { seID });
nw.setTileID(UpsampledQuadtreeNode { nwID });
ne.setTileID(UpsampledQuadtreeNode { neID });

const GlobeRectangle& rectangle = pRegion->getRectangle();
CesiumGeospatial::Cartographic center = rectangle.computeCenter();
double minimumHeight = pRegion->getMinimumHeight();
double maximumHeight = pRegion->getMaximumHeight();

sw.setBoundingVolume(BoundingRegionWithLooseFittingHeights(BoundingRegion(
GlobeRectangle(rectangle.getWest(), rectangle.getSouth(), center.longitude, center.latitude),
unprojectRectangleSimple(projection, tilingScheme.tileToRectangle(swID)),
minimumHeight,
maximumHeight
)));
se.setBoundingVolume(BoundingRegionWithLooseFittingHeights(BoundingRegion(
GlobeRectangle(center.longitude, rectangle.getSouth(), rectangle.getEast(), center.latitude),
unprojectRectangleSimple(projection, tilingScheme.tileToRectangle(seID)),
minimumHeight,
maximumHeight
)));
nw.setBoundingVolume(BoundingRegionWithLooseFittingHeights(BoundingRegion(
GlobeRectangle(rectangle.getWest(), center.latitude, center.longitude, rectangle.getNorth()),
unprojectRectangleSimple(projection, tilingScheme.tileToRectangle(nwID)),
minimumHeight,
maximumHeight
)));
ne.setBoundingVolume(BoundingRegionWithLooseFittingHeights(BoundingRegion(
GlobeRectangle(center.longitude, center.latitude, rectangle.getEast(), rectangle.getNorth()),
unprojectRectangleSimple(projection, tilingScheme.tileToRectangle(neID)),
minimumHeight,
maximumHeight
)));
Expand Down Expand Up @@ -645,7 +669,7 @@ namespace Cesium3DTiles {

void Tile::upsampleParent(std::vector<CesiumGeospatial::Projection>&& projections) {
Tile* pParent = this->getParent();
const QuadtreeChild* pSubdividedParentID = std::get_if<QuadtreeChild>(&this->getTileID());
const UpsampledQuadtreeNode* pSubdividedParentID = std::get_if<UpsampledQuadtreeNode>(&this->getTileID());

assert(pParent != nullptr);
assert(pParent->getState() == LoadState::Done);
Expand Down
2 changes: 1 addition & 1 deletion Cesium3DTiles/src/Tileset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1277,7 +1277,7 @@ namespace Cesium3DTiles {
});
}

std::string operator()(QuadtreeChild /*subdividedParent*/) {
std::string operator()(UpsampledQuadtreeNode /*subdividedParent*/) {
return std::string();
}
};
Expand Down
32 changes: 20 additions & 12 deletions Cesium3DTiles/src/upsampleGltfForRasterOverlays.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ namespace Cesium3DTiles {
Model& model,
Mesh& mesh,
MeshPrimitive& primitive,
CesiumGeometry::QuadtreeChild childID
CesiumGeometry::UpsampledQuadtreeNode childID
);

struct FloatVertexAttribute {
Expand Down Expand Up @@ -72,14 +72,22 @@ namespace Cesium3DTiles {
static void addSkirts(std::vector<float>& output,
std::vector<uint32_t>& indices,
std::vector<FloatVertexAttribute>& attributes,
CesiumGeometry::QuadtreeChild childID,
CesiumGeometry::UpsampledQuadtreeNode childID,
SkirtMeshMetadata &currentSkirt,
const SkirtMeshMetadata &parentSkirt,
EdgeIndices &edgeIndices,
int64_t vertexSizeFloats,
int32_t positionAttributeIndex);

Model upsampleGltfForRasterOverlays(const Model& parentModel, CesiumGeometry::QuadtreeChild childID) {
static bool isWestChild(CesiumGeometry::UpsampledQuadtreeNode childID) {
return (childID.tileID.x % 2) == 0;
}

static bool isSouthChild(CesiumGeometry::UpsampledQuadtreeNode childID) {
return (childID.tileID.y % 2) == 0;
}

Model upsampleGltfForRasterOverlays(const Model& parentModel, CesiumGeometry::UpsampledQuadtreeNode childID) {
Model result;

// Copy the entire parent model except for the buffers, bufferViews, and accessors, which we'll be rewriting.
Expand Down Expand Up @@ -283,7 +291,7 @@ namespace Cesium3DTiles {
Model& model,
Mesh& /*mesh*/,
MeshPrimitive& primitive,
CesiumGeometry::QuadtreeChild childID
CesiumGeometry::UpsampledQuadtreeNode childID
) {
// Add up the per-vertex size of all attributes and create buffers, bufferViews, and accessors
std::vector<FloatVertexAttribute> attributes;
Expand Down Expand Up @@ -392,8 +400,8 @@ namespace Cesium3DTiles {
primitive.attributes.erase(attribute);
}

bool keepAboveU = childID == CesiumGeometry::QuadtreeChild::LowerRight || childID == CesiumGeometry::QuadtreeChild::UpperRight;
bool keepAboveV = childID == CesiumGeometry::QuadtreeChild::UpperLeft || childID == CesiumGeometry::QuadtreeChild::UpperRight;
bool keepAboveU = !isWestChild(childID);
bool keepAboveV = !isSouthChild(childID);

AccessorView<glm::vec2> uvView(parentModel, uvAccessorIndex);
AccessorView<TIndex> indicesView(parentModel, primitive.indices);
Expand Down Expand Up @@ -723,7 +731,7 @@ namespace Cesium3DTiles {
static void addSkirts(std::vector<float>& output,
std::vector<uint32_t>& indices,
std::vector<FloatVertexAttribute>& attributes,
CesiumGeometry::QuadtreeChild childID,
CesiumGeometry::UpsampledQuadtreeNode childID,
SkirtMeshMetadata &currentSkirt,
const SkirtMeshMetadata &parentSkirt,
EdgeIndices &edgeIndices,
Expand All @@ -736,7 +744,7 @@ namespace Cesium3DTiles {
shortestSkirtHeight = glm::min(shortestSkirtHeight, parentSkirt.skirtNorthHeight);

// west
if (childID == CesiumGeometry::QuadtreeChild::LowerLeft || childID == CesiumGeometry::QuadtreeChild::UpperLeft) {
if (isWestChild(childID)) {
currentSkirt.skirtWestHeight = parentSkirt.skirtWestHeight;
}
else {
Expand All @@ -763,7 +771,7 @@ namespace Cesium3DTiles {
positionAttributeIndex);

// south
if (childID == CesiumGeometry::QuadtreeChild::LowerLeft || childID == CesiumGeometry::QuadtreeChild::LowerRight) {
if (isSouthChild(childID)) {
currentSkirt.skirtSouthHeight = parentSkirt.skirtSouthHeight;
}
else {
Expand All @@ -790,7 +798,7 @@ namespace Cesium3DTiles {
positionAttributeIndex);

// east
if (childID == CesiumGeometry::QuadtreeChild::LowerRight || childID == CesiumGeometry::QuadtreeChild::UpperRight) {
if (!isWestChild(childID)) {
currentSkirt.skirtEastHeight = parentSkirt.skirtEastHeight;
}
else {
Expand All @@ -817,7 +825,7 @@ namespace Cesium3DTiles {
positionAttributeIndex);

// north
if (childID == CesiumGeometry::QuadtreeChild::UpperLeft || childID == CesiumGeometry::QuadtreeChild::UpperRight) {
if (!isSouthChild(childID)) {
currentSkirt.skirtNorthHeight = parentSkirt.skirtNorthHeight;
}
else {
Expand Down Expand Up @@ -849,7 +857,7 @@ namespace Cesium3DTiles {
Model& model,
Mesh& mesh,
MeshPrimitive& primitive,
CesiumGeometry::QuadtreeChild childID
CesiumGeometry::UpsampledQuadtreeNode childID
) {
if (
primitive.mode != MeshPrimitive::Mode::TRIANGLES ||
Expand Down
2 changes: 1 addition & 1 deletion Cesium3DTiles/src/upsampleGltfForRasterOverlays.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@

namespace Cesium3DTiles {

CesiumGltf::Model upsampleGltfForRasterOverlays(const CesiumGltf::Model& parentModel, CesiumGeometry::QuadtreeChild childID);
CesiumGltf::Model upsampleGltfForRasterOverlays(const CesiumGltf::Model& parentModel, CesiumGeometry::UpsampledQuadtreeNode childID);

}
Loading

0 comments on commit 82361b3

Please sign in to comment.