Merge pull request #200 from CesiumGS/add-gltfupaxis-support
Add gltfupaxis support
This commit is contained in:
commit
8b0041c452
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
- Gave glTFs created from quantized-mesh terrain tiles a more sensible material with a `metallicFactor` of 0.0 and a `roughnessFactor` of 1.0. Previously the default glTF material was used, which has a `metallicFactor` of 1.0, leading to an undesirable appearance.
|
||||
- Reported zero-length images as non-errors as `BingMapsRasterOverlay` purposely requests that the Bing servers return a zero-length image for non-existent tiles.
|
||||
- Added an `Axis` enum and `AxisTransforms` class for coordinate system transforms
|
||||
- Added support for the legacy `gltfUpVector` string property in the `asset` part of tilesets. The up vector is read and passed as an `Axis` in the `extras["gltfUpVector"]` property, so that receivers may rotate the glTF model's up-vector to match the Z-up convention of 3D Tiles.
|
||||
|
||||
### v0.1.0 - 2021-03-30
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include "Cesium3DTiles/ViewUpdateResult.h"
|
||||
#include "CesiumAsync/AsyncSystem.h"
|
||||
#include "CesiumAsync/IAssetRequest.h"
|
||||
#include "CesiumGeometry/Axis.h"
|
||||
#include "CesiumGeometry/QuadtreeTileAvailability.h"
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
|
|
@ -417,6 +418,19 @@ public:
|
|||
return this->_supportsRasterOverlays;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the value indicating the glTF up-axis.
|
||||
*
|
||||
* This function is not supposed to be called by clients.
|
||||
*
|
||||
* The value indicates the axis, via 0=X, 1=Y, 2=Z.
|
||||
*
|
||||
* @return The value representing the axis
|
||||
*/
|
||||
CesiumGeometry::Axis getGltfUpAxis() const noexcept {
|
||||
return this->_gltfUpAxis;
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief The result of traversing one branch of the tile hierarchy.
|
||||
|
|
@ -713,6 +727,18 @@ private:
|
|||
|
||||
bool _supportsRasterOverlays;
|
||||
|
||||
/**
|
||||
* @brief The axis that was declared as the "up-axis" for glTF content.
|
||||
*
|
||||
* The glTF specification mandates that the Y-axis is the "up"-axis, so the
|
||||
* default value is {@link Axis::Y}. Older tilesets may contain a string
|
||||
* property in the "assets" dictionary, named "gltfUpAxis", indicating a
|
||||
* different up-axis. Although the "gltfUpAxis" property is no longer part of
|
||||
* the 3D tiles specification, it is still considered for backward
|
||||
* compatibility.
|
||||
*/
|
||||
CesiumGeometry::Axis _gltfUpAxis;
|
||||
|
||||
static void addTileToLoadQueue(
|
||||
std::vector<LoadRecord>& loadQueue,
|
||||
const ViewState& viewState,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include "CesiumAsync/IAssetAccessor.h"
|
||||
#include "CesiumAsync/IAssetResponse.h"
|
||||
#include "CesiumAsync/ITaskProcessor.h"
|
||||
#include "CesiumGeometry/Axis.h"
|
||||
#include "TileUtilities.h"
|
||||
#include "upsampleGltfForRasterOverlays.h"
|
||||
|
||||
|
|
@ -234,10 +235,12 @@ void Tile::loadContent() {
|
|||
};
|
||||
TileContentLoadInput loadInput(tileset.getExternals().pLogger, *this);
|
||||
|
||||
const CesiumGeometry::Axis gltfUpAxis = tileset.getGltfUpAxis();
|
||||
std::move(maybeRequestFuture.value())
|
||||
.thenInWorkerThread(
|
||||
[loadInput = std::move(loadInput),
|
||||
projections = std::move(projections),
|
||||
gltfUpAxis,
|
||||
pPrepareRendererResources =
|
||||
tileset.getExternals().pPrepareRendererResources,
|
||||
pLogger = tileset.getExternals().pLogger](
|
||||
|
|
@ -287,6 +290,12 @@ void Tile::loadContent() {
|
|||
void* pRendererResources = nullptr;
|
||||
|
||||
if (pContent->model) {
|
||||
|
||||
// TODO The `extras` are currently the only way to pass
|
||||
// arbitrary information to the consumer, so the up-axis
|
||||
// is stored here:
|
||||
pContent->model.value().extras["gltfUpAxis"] = gltfUpAxis;
|
||||
|
||||
const BoundingVolume& boundingVolume =
|
||||
loadInput.tileBoundingVolume;
|
||||
Tile::generateTextureCoordinates(
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include "CesiumAsync/IAssetAccessor.h"
|
||||
#include "CesiumAsync/IAssetResponse.h"
|
||||
#include "CesiumAsync/ITaskProcessor.h"
|
||||
#include "CesiumGeometry/Axis.h"
|
||||
#include "CesiumGeometry/QuadtreeTileAvailability.h"
|
||||
#include "CesiumGeospatial/GeographicProjection.h"
|
||||
#include "CesiumUtility/JsonHelpers.h"
|
||||
|
|
@ -57,7 +58,8 @@ Tileset::Tileset(
|
|||
_loadedTiles(),
|
||||
_overlays(*this),
|
||||
_tileDataBytes(0),
|
||||
_supportsRasterOverlays(false) {
|
||||
_supportsRasterOverlays(false),
|
||||
_gltfUpAxis(CesiumGeometry::Axis::Y) {
|
||||
++this->_loadsInProgress;
|
||||
this->_loadTilesetJson(url);
|
||||
}
|
||||
|
|
@ -508,6 +510,55 @@ void Tileset::_loadTilesetJson(
|
|||
});
|
||||
}
|
||||
|
||||
namespace {
|
||||
/**
|
||||
* @brief Obtains the up-axis that should be used for glTF content of the
|
||||
* tileset.
|
||||
*
|
||||
* If the given tileset JSON does not contain an `asset.gltfUpAxis` string
|
||||
* property, then the default value of CesiumGeometry::Axis::Y is returned.
|
||||
*
|
||||
* Otherwise, a warning is printed, saying that the `gltfUpAxis` property is
|
||||
* not strictly compliant to the 3D tiles standard, and the return value
|
||||
* will depend on the string value of this property, which may be "X", "Y", or
|
||||
* "Z", case-insensitively, causing CesiumGeometry::Axis::X,
|
||||
* CesiumGeometry::Axis::Y, or CesiumGeometry::Axis::Z to be returned,
|
||||
* respectively.
|
||||
*
|
||||
* @param tileset The tileset JSON
|
||||
* @return The up-axis to use for glTF content
|
||||
*/
|
||||
CesiumGeometry::Axis obtainGltfUpAxis(const rapidjson::Document& tileset) {
|
||||
auto assetIt = tileset.FindMember("asset");
|
||||
if (assetIt == tileset.MemberEnd()) {
|
||||
return CesiumGeometry::Axis::Y;
|
||||
}
|
||||
const rapidjson::Value& assetJson = assetIt->value;
|
||||
auto gltfUpAxisIt = assetJson.FindMember("gltfUpAxis");
|
||||
if (gltfUpAxisIt == assetJson.MemberEnd()) {
|
||||
return CesiumGeometry::Axis::Y;
|
||||
}
|
||||
|
||||
SPDLOG_WARN("The tileset contains a gltfUpAxis property. "
|
||||
"This property is not part of the specification. "
|
||||
"All glTF content should use the Y-axis as the up-axis.");
|
||||
|
||||
const rapidjson::Value& gltfUpAxisJson = gltfUpAxisIt->value;
|
||||
auto gltfUpAxisString = std::string(gltfUpAxisJson.GetString());
|
||||
if (gltfUpAxisString == "X" || gltfUpAxisString == "x") {
|
||||
return CesiumGeometry::Axis::X;
|
||||
}
|
||||
if (gltfUpAxisString == "Y" || gltfUpAxisString == "y") {
|
||||
return CesiumGeometry::Axis::Y;
|
||||
}
|
||||
if (gltfUpAxisString == "Z" || gltfUpAxisString == "z") {
|
||||
return CesiumGeometry::Axis::Z;
|
||||
}
|
||||
SPDLOG_WARN("Unknown gltfUpAxis: {}, using default (Y)", gltfUpAxisString);
|
||||
return CesiumGeometry::Axis::Y;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
/*static*/ Tileset::LoadResult Tileset::_handleTilesetResponse(
|
||||
std::shared_ptr<IAssetRequest>&& pRequest,
|
||||
std::unique_ptr<TileContext>&& pContext,
|
||||
|
|
@ -547,6 +598,8 @@ void Tileset::_loadTilesetJson(
|
|||
return LoadResult{std::move(pContext), nullptr, false};
|
||||
}
|
||||
|
||||
pContext->pTileset->_gltfUpAxis = obtainGltfUpAxis(tileset);
|
||||
|
||||
std::unique_ptr<Tile> pRootTile = std::make_unique<Tile>();
|
||||
pRootTile->setContext(pContext.get());
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
#pragma once
|
||||
|
||||
#include "CesiumGeometry/Library.h"
|
||||
|
||||
namespace CesiumGeometry {
|
||||
|
||||
/**
|
||||
* @brief An enum describing the x, y, and z axes
|
||||
*/
|
||||
enum CESIUMGEOMETRY_API Axis {
|
||||
/**
|
||||
* @brief The x-axis
|
||||
*/
|
||||
X,
|
||||
|
||||
/**
|
||||
* @brief The y-axis
|
||||
*/
|
||||
Y,
|
||||
|
||||
/**
|
||||
* @brief The z-axis
|
||||
*/
|
||||
Z
|
||||
};
|
||||
} // namespace CesiumGeometry
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
#pragma once
|
||||
|
||||
#include "CesiumGeometry/Library.h"
|
||||
#include <glm/mat3x3.hpp>
|
||||
|
||||
namespace CesiumGeometry {
|
||||
|
||||
/**
|
||||
* @brief Coordinate system conversion matrices
|
||||
*/
|
||||
struct CESIUMGEOMETRY_API AxisTransforms final {
|
||||
|
||||
/**
|
||||
* @brief A matrix to convert from y-up to z-up orientation,
|
||||
* by rotating about PI/2 around the x-axis
|
||||
*/
|
||||
static const glm::dmat4 Y_UP_TO_Z_UP;
|
||||
|
||||
/**
|
||||
* @brief A matrix to convert from z-up to y-up orientation,
|
||||
* by rotating about -PI/2 around the x-axis
|
||||
*/
|
||||
static const glm::dmat4 Z_UP_TO_Y_UP;
|
||||
|
||||
/**
|
||||
* @brief A matrix to convert from x-up to z-up orientation,
|
||||
* by rotating about -PI/2 around the y-axis
|
||||
*/
|
||||
static const glm::dmat4 X_UP_TO_Z_UP;
|
||||
|
||||
/**
|
||||
* @brief A matrix to convert from z-up to x-up orientation,
|
||||
* by rotating about PI/2 around the y-axis
|
||||
*/
|
||||
static const glm::dmat4 Z_UP_TO_X_UP;
|
||||
|
||||
/**
|
||||
* @brief A matrix to convert from x-up to y-up orientation,
|
||||
* by rotating about PI/2 around the z-axis
|
||||
*/
|
||||
static const glm::dmat4 X_UP_TO_Y_UP;
|
||||
|
||||
/**
|
||||
* @brief A matrix to convert from y-up to x-up orientation,
|
||||
* by rotating about -PI/2 around the z-axis
|
||||
*/
|
||||
static const glm::dmat4 Y_UP_TO_X_UP;
|
||||
};
|
||||
|
||||
} // namespace CesiumGeometry
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "CesiumGeometry/OctreeTileID.h"
|
||||
#include "CesiumGeometry/Library.h"
|
||||
|
||||
namespace CesiumGeometry {
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,65 @@
|
|||
#include "CesiumGeometry/AxisTransforms.h"
|
||||
#include <glm/mat3x3.hpp>
|
||||
|
||||
namespace CesiumGeometry {
|
||||
|
||||
namespace {
|
||||
// Initialize with a function instead of inline to avoid an
|
||||
// internal compiler error in MSVC v14.27.29110.
|
||||
glm::dmat4 createYupToZup() {
|
||||
return glm::dmat4(
|
||||
glm::dvec4(1.0, 0.0, 0.0, 0.0),
|
||||
glm::dvec4(0.0, 0.0, 1.0, 0.0),
|
||||
glm::dvec4(0.0, -1.0, 0.0, 0.0),
|
||||
glm::dvec4(0.0, 0.0, 0.0, 1.0));
|
||||
}
|
||||
|
||||
glm::dmat4 createZupToYup() {
|
||||
return glm::dmat4(
|
||||
glm::dvec4(1.0, 0.0, 0.0, 0.0),
|
||||
glm::dvec4(0.0, 0.0, -1.0, 0.0),
|
||||
glm::dvec4(0.0, 1.0, 0.0, 0.0),
|
||||
glm::dvec4(0.0, 0.0, 0.0, 1.0));
|
||||
}
|
||||
|
||||
glm::dmat4 createXupToZup() {
|
||||
return glm::dmat4(
|
||||
glm::dvec4(0.0, 0.0, 1.0, 0.0),
|
||||
glm::dvec4(0.0, 1.0, 0.0, 0.0),
|
||||
glm::dvec4(-1.0, 0.0, 0.0, 0.0),
|
||||
glm::dvec4(0.0, 0.0, 0.0, 1.0));
|
||||
}
|
||||
|
||||
glm::dmat4 createZupToXup() {
|
||||
return glm::dmat4(
|
||||
glm::dvec4(0.0, 0.0, -1.0, 0.0),
|
||||
glm::dvec4(0.0, 1.0, 0.0, 0.0),
|
||||
glm::dvec4(1.0, 0.0, 0.0, 0.0),
|
||||
glm::dvec4(0.0, 0.0, 0.0, 1.0));
|
||||
}
|
||||
|
||||
glm::dmat4 createXupToYup() {
|
||||
return glm::dmat4(
|
||||
glm::dvec4(0.0, 1.0, 0.0, 0.0),
|
||||
glm::dvec4(-1.0, 0.0, 0.0, 0.0),
|
||||
glm::dvec4(0.0, 0.0, 1.0, 0.0),
|
||||
glm::dvec4(0.0, 0.0, 0.0, 1.0));
|
||||
}
|
||||
|
||||
glm::dmat4 createYupToXup() {
|
||||
return glm::dmat4(
|
||||
glm::dvec4(0.0, -1.0, 0.0, 0.0),
|
||||
glm::dvec4(1.0, 0.0, 0.0, 0.0),
|
||||
glm::dvec4(0.0, 0.0, 1.0, 0.0),
|
||||
glm::dvec4(0.0, 0.0, 0.0, 1.0));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
const glm::dmat4 AxisTransforms::Y_UP_TO_Z_UP = createYupToZup();
|
||||
const glm::dmat4 AxisTransforms::Z_UP_TO_Y_UP = createZupToYup();
|
||||
const glm::dmat4 AxisTransforms::X_UP_TO_Z_UP = createXupToZup();
|
||||
const glm::dmat4 AxisTransforms::Z_UP_TO_X_UP = createZupToXup();
|
||||
const glm::dmat4 AxisTransforms::X_UP_TO_Y_UP = createXupToYup();
|
||||
const glm::dmat4 AxisTransforms::Y_UP_TO_X_UP = createYupToXup();
|
||||
|
||||
} // namespace CesiumGeometry
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
#include "CesiumGeometry/AxisTransforms.h"
|
||||
#include "CesiumUtility/Math.h"
|
||||
#include "catch2/catch.hpp"
|
||||
|
||||
TEST_CASE("AxisTransforms convert the axes correctly") {
|
||||
|
||||
glm::dvec4 X_AXIS{1.0, 0.0, 0.0, 0.0};
|
||||
glm::dvec4 Y_AXIS{0.0, 1.0, 0.0, 0.0};
|
||||
glm::dvec4 Z_AXIS{0.0, 0.0, 1.0, 0.0};
|
||||
|
||||
SECTION("Y_UP_TO_Z_UP transforms X to X, Y to -Z, and Z to Y") {
|
||||
REQUIRE(X_AXIS * CesiumGeometry::AxisTransforms::Y_UP_TO_Z_UP == X_AXIS);
|
||||
REQUIRE(Y_AXIS * CesiumGeometry::AxisTransforms::Y_UP_TO_Z_UP == -Z_AXIS);
|
||||
REQUIRE(Z_AXIS * CesiumGeometry::AxisTransforms::Y_UP_TO_Z_UP == Y_AXIS);
|
||||
}
|
||||
SECTION("Z_UP_TO_Y_UP transforms X to X, Y to Z, and Z to -Y") {
|
||||
REQUIRE(X_AXIS * CesiumGeometry::AxisTransforms::Z_UP_TO_Y_UP == X_AXIS);
|
||||
REQUIRE(Y_AXIS * CesiumGeometry::AxisTransforms::Z_UP_TO_Y_UP == Z_AXIS);
|
||||
REQUIRE(Z_AXIS * CesiumGeometry::AxisTransforms::Z_UP_TO_Y_UP == -Y_AXIS);
|
||||
}
|
||||
|
||||
SECTION("X_UP_TO_Z_UP transforms X to -Z, Y to Y, and Z to X") {
|
||||
REQUIRE(X_AXIS * CesiumGeometry::AxisTransforms::X_UP_TO_Z_UP == -Z_AXIS);
|
||||
REQUIRE(Y_AXIS * CesiumGeometry::AxisTransforms::X_UP_TO_Z_UP == Y_AXIS);
|
||||
REQUIRE(Z_AXIS * CesiumGeometry::AxisTransforms::X_UP_TO_Z_UP == X_AXIS);
|
||||
}
|
||||
SECTION("Z_UP_TO_X_UP transforms X to Z, Y to Y, and Z to -X") {
|
||||
REQUIRE(X_AXIS * CesiumGeometry::AxisTransforms::Z_UP_TO_X_UP == Z_AXIS);
|
||||
REQUIRE(Y_AXIS * CesiumGeometry::AxisTransforms::Z_UP_TO_X_UP == Y_AXIS);
|
||||
REQUIRE(Z_AXIS * CesiumGeometry::AxisTransforms::Z_UP_TO_X_UP == -X_AXIS);
|
||||
}
|
||||
|
||||
SECTION("X_UP_TO_Y_UP transforms X to -Y, Y to X, and Z to Z") {
|
||||
REQUIRE(X_AXIS * CesiumGeometry::AxisTransforms::X_UP_TO_Y_UP == -Y_AXIS);
|
||||
REQUIRE(Y_AXIS * CesiumGeometry::AxisTransforms::X_UP_TO_Y_UP == X_AXIS);
|
||||
REQUIRE(Z_AXIS * CesiumGeometry::AxisTransforms::X_UP_TO_Y_UP == Z_AXIS);
|
||||
}
|
||||
SECTION("Y_UP_TO_X_UP transforms X to Y, Y to -X, and Z to Z") {
|
||||
REQUIRE(X_AXIS * CesiumGeometry::AxisTransforms::Y_UP_TO_X_UP == Y_AXIS);
|
||||
REQUIRE(Y_AXIS * CesiumGeometry::AxisTransforms::Y_UP_TO_X_UP == -X_AXIS);
|
||||
REQUIRE(Z_AXIS * CesiumGeometry::AxisTransforms::Y_UP_TO_X_UP == Z_AXIS);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue