-
Notifications
You must be signed in to change notification settings - Fork 214
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move more functionality to Cesium3DTilesContent.
- Loading branch information
Showing
52 changed files
with
469 additions
and
437 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
96 changes: 96 additions & 0 deletions
96
Cesium3DTilesContent/include/Cesium3DTilesContent/GltfUtilities.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
#pragma once | ||
|
||
#include "Library.h" | ||
|
||
#include <CesiumGeospatial/BoundingRegion.h> | ||
#include <CesiumGeospatial/GlobeRectangle.h> | ||
|
||
#include <glm/fwd.hpp> | ||
|
||
#include <string_view> | ||
#include <vector> | ||
|
||
namespace CesiumGltf { | ||
struct Model; | ||
} | ||
|
||
namespace Cesium3DTilesSelection { | ||
/** | ||
* A collection of utility functions that are used to process and transform a | ||
* gltf model | ||
*/ | ||
struct CESIUM3DTILESCONTENT_API GltfUtilities { | ||
/** | ||
* @brief Applies the glTF's RTC_CENTER, if any, to the given transform. | ||
* | ||
* If the glTF has a `CESIUM_RTC` extension, this function will multiply the | ||
* given matrix with the (translation) matrix that is created from the | ||
* `RTC_CENTER` in the. If the given model does not have this extension, then | ||
* this function will return the `rootTransform` unchanged. | ||
* | ||
* @param model The glTF model | ||
* @param rootTransform The matrix that will be multiplied with the transform | ||
* @return The result of multiplying the `RTC_CENTER` with the | ||
* `rootTransform`. | ||
*/ | ||
static glm::dmat4x4 applyRtcCenter( | ||
const CesiumGltf::Model& gltf, | ||
const glm::dmat4x4& rootTransform); | ||
|
||
/** | ||
* @brief Applies the glTF's `gltfUpAxis`, if any, to the given transform. | ||
* | ||
* By default, the up-axis of a glTF model will the the Y-axis. | ||
* | ||
* If the tileset that contained the model had the `asset.gltfUpAxis` string | ||
* property, then the information about the up-axis has been stored in as a | ||
* number property called `gltfUpAxis` in the `extras` of the given model. | ||
* | ||
* Depending on whether this value is `CesiumGeometry::Axis::X`, `Y`, or `Z`, | ||
* the given matrix will be multiplied with a matrix that converts the | ||
* respective axis to be the Z-axis, as required by the 3D Tiles standard. | ||
* | ||
* @param model The glTF model | ||
* @param rootTransform The matrix that will be multiplied with the transform | ||
* @return The result of multiplying the `rootTransform` with the | ||
* `gltfUpAxis`. | ||
*/ | ||
static glm::dmat4x4 applyGltfUpAxisTransform( | ||
const CesiumGltf::Model& model, | ||
const glm::dmat4x4& rootTransform); | ||
|
||
/** | ||
* @brief Computes a bounding region from the vertex positions in a glTF | ||
* model. | ||
* | ||
* If the glTF model spans the anti-meridian, the west and east longitude | ||
* values will be in the usual -PI to PI range, but east will have a smaller | ||
* value than west. | ||
* | ||
* If the glTF contains no geometry, the returned region's rectangle | ||
* will be {@link GlobeRectangle::EMPTY}, its minimum height will be 1.0, and | ||
* its maximum height will be -1.0 (the minimum will be greater than the | ||
* maximum). | ||
* | ||
* @param gltf The model. | ||
* @param transform The transform from model coordinates to ECEF coordinates. | ||
* @return The computed bounding region. | ||
*/ | ||
static CesiumGeospatial::BoundingRegion computeBoundingRegion( | ||
const CesiumGltf::Model& gltf, | ||
const glm::dmat4& transform); | ||
|
||
/** | ||
* @brief Parse the copyright field of a glTF model and return the individual | ||
* credits. | ||
* | ||
* Credits are read from the glTF's asset.copyright field. This method assumes | ||
* that individual credits are separated by semicolons. | ||
* | ||
* @param gltf The model. | ||
* @return The credits from the glTF. | ||
*/ | ||
static std::vector<std::string_view> | ||
parseGltfCopyright(const CesiumGltf::Model& gltf); | ||
}; | ||
} // namespace Cesium3DTilesSelection |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
1 change: 0 additions & 1 deletion
1
...DTilesSelection/src/SubtreeAvailability.h → ...esium3DTilesContent/SubtreeAvailability.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
5 changes: 2 additions & 3 deletions
5
...ilesSelection/src/CmptToGltfConverter.cpp → ...DTilesContent/src/CmptToGltfConverter.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...um3DTilesSelection/src/GltfConverters.cpp → Cesium3DTilesContent/src/GltfConverters.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
#include <Cesium3DTilesContent/GltfUtilities.h> | ||
#include <Cesium3DTilesContent/SkirtMeshMetadata.h> | ||
#include <CesiumGeometry/Axis.h> | ||
#include <CesiumGeometry/Transforms.h> | ||
#include <CesiumGeospatial/BoundingRegionBuilder.h> | ||
#include <CesiumGltf/AccessorView.h> | ||
#include <CesiumGltf/ExtensionCesiumRTC.h> | ||
|
||
#include <vector> | ||
|
||
namespace Cesium3DTilesSelection { | ||
/*static*/ glm::dmat4x4 GltfUtilities::applyRtcCenter( | ||
const CesiumGltf::Model& gltf, | ||
const glm::dmat4x4& rootTransform) { | ||
const CesiumGltf::ExtensionCesiumRTC* cesiumRTC = | ||
gltf.getExtension<CesiumGltf::ExtensionCesiumRTC>(); | ||
if (cesiumRTC == nullptr) { | ||
return rootTransform; | ||
} | ||
const std::vector<double>& rtcCenter = cesiumRTC->center; | ||
if (rtcCenter.size() != 3) { | ||
return rootTransform; | ||
} | ||
const double x = rtcCenter[0]; | ||
const double y = rtcCenter[1]; | ||
const double z = rtcCenter[2]; | ||
const glm::dmat4x4 rtcTransform( | ||
glm::dvec4(1.0, 0.0, 0.0, 0.0), | ||
glm::dvec4(0.0, 1.0, 0.0, 0.0), | ||
glm::dvec4(0.0, 0.0, 1.0, 0.0), | ||
glm::dvec4(x, y, z, 1.0)); | ||
return rootTransform * rtcTransform; | ||
} | ||
|
||
/*static*/ glm::dmat4x4 GltfUtilities::applyGltfUpAxisTransform( | ||
const CesiumGltf::Model& model, | ||
const glm::dmat4x4& rootTransform) { | ||
auto gltfUpAxisIt = model.extras.find("gltfUpAxis"); | ||
if (gltfUpAxisIt == model.extras.end()) { | ||
// The default up-axis of glTF is the Y-axis, and no other | ||
// up-axis was specified. Transform the Y-axis to the Z-axis, | ||
// to match the 3D Tiles specification | ||
return rootTransform * CesiumGeometry::Transforms::Y_UP_TO_Z_UP; | ||
} | ||
const CesiumUtility::JsonValue& gltfUpAxis = gltfUpAxisIt->second; | ||
int gltfUpAxisValue = static_cast<int>(gltfUpAxis.getSafeNumberOrDefault(1)); | ||
if (gltfUpAxisValue == static_cast<int>(CesiumGeometry::Axis::X)) { | ||
return rootTransform * CesiumGeometry::Transforms::X_UP_TO_Z_UP; | ||
} else if (gltfUpAxisValue == static_cast<int>(CesiumGeometry::Axis::Y)) { | ||
return rootTransform * CesiumGeometry::Transforms::Y_UP_TO_Z_UP; | ||
} else if (gltfUpAxisValue == static_cast<int>(CesiumGeometry::Axis::Z)) { | ||
// No transform required | ||
} | ||
return rootTransform; | ||
} | ||
|
||
/*static*/ CesiumGeospatial::BoundingRegion | ||
GltfUtilities::computeBoundingRegion( | ||
const CesiumGltf::Model& gltf, | ||
const glm::dmat4& transform) { | ||
glm::dmat4 rootTransform = transform; | ||
rootTransform = applyRtcCenter(gltf, rootTransform); | ||
rootTransform = applyGltfUpAxisTransform(gltf, rootTransform); | ||
|
||
// When computing the tile's bounds, ignore tiles that are less than 1/1000th | ||
// of a tile width from the North or South pole. Longitudes cannot be trusted | ||
// at such extreme latitudes. | ||
CesiumGeospatial::BoundingRegionBuilder computedBounds; | ||
|
||
gltf.forEachPrimitiveInScene( | ||
-1, | ||
[&rootTransform, &computedBounds]( | ||
const CesiumGltf::Model& gltf_, | ||
const CesiumGltf::Node& /*node*/, | ||
const CesiumGltf::Mesh& /*mesh*/, | ||
const CesiumGltf::MeshPrimitive& primitive, | ||
const glm::dmat4& nodeTransform) { | ||
auto positionIt = primitive.attributes.find("POSITION"); | ||
if (positionIt == primitive.attributes.end()) { | ||
return; | ||
} | ||
|
||
const int positionAccessorIndex = positionIt->second; | ||
if (positionAccessorIndex < 0 || | ||
positionAccessorIndex >= static_cast<int>(gltf_.accessors.size())) { | ||
return; | ||
} | ||
|
||
const glm::dmat4 fullTransform = rootTransform * nodeTransform; | ||
|
||
const CesiumGltf::AccessorView<glm::vec3> positionView( | ||
gltf_, | ||
positionAccessorIndex); | ||
if (positionView.status() != CesiumGltf::AccessorViewStatus::Valid) { | ||
return; | ||
} | ||
|
||
std::optional<SkirtMeshMetadata> skirtMeshMetadata = | ||
SkirtMeshMetadata::parseFromGltfExtras(primitive.extras); | ||
int64_t vertexBegin, vertexEnd; | ||
if (skirtMeshMetadata.has_value()) { | ||
vertexBegin = skirtMeshMetadata->noSkirtVerticesBegin; | ||
vertexEnd = skirtMeshMetadata->noSkirtVerticesBegin + | ||
skirtMeshMetadata->noSkirtVerticesCount; | ||
} else { | ||
vertexBegin = 0; | ||
vertexEnd = positionView.size(); | ||
} | ||
|
||
for (int64_t i = vertexBegin; i < vertexEnd; ++i) { | ||
// Get the ECEF position | ||
const glm::vec3 position = positionView[i]; | ||
const glm::dvec3 positionEcef = | ||
glm::dvec3(fullTransform * glm::dvec4(position, 1.0)); | ||
|
||
// Convert it to cartographic | ||
std::optional<CesiumGeospatial::Cartographic> cartographic = | ||
CesiumGeospatial::Ellipsoid::WGS84.cartesianToCartographic( | ||
positionEcef); | ||
if (!cartographic) { | ||
continue; | ||
} | ||
|
||
computedBounds.expandToIncludePosition(*cartographic); | ||
} | ||
}); | ||
|
||
return computedBounds.toRegion(); | ||
} | ||
|
||
std::vector<std::string_view> | ||
GltfUtilities::parseGltfCopyright(const CesiumGltf::Model& gltf) { | ||
std::vector<std::string_view> result; | ||
if (gltf.asset.copyright) { | ||
const std::string_view copyright = *gltf.asset.copyright; | ||
if (copyright.size() > 0) { | ||
size_t start = 0; | ||
size_t end; | ||
size_t ltrim; | ||
size_t rtrim; | ||
do { | ||
ltrim = copyright.find_first_not_of(" \t", start); | ||
end = copyright.find(';', ltrim); | ||
rtrim = copyright.find_last_not_of(" \t", end - 1); | ||
result.emplace_back(copyright.substr(ltrim, rtrim - ltrim + 1)); | ||
start = end + 1; | ||
} while (end != std::string::npos); | ||
} | ||
} | ||
|
||
return result; | ||
} | ||
} // namespace Cesium3DTilesSelection |
Oops, something went wrong.