3 #include "CesiumGltf/ImageAsset.h"
4 #include "CesiumGltf/KhrTextureTransform.h"
5 #include "CesiumGltf/PropertyTextureProperty.h"
6 #include "CesiumGltf/PropertyTransformations.h"
7 #include "CesiumGltf/PropertyTypeTraits.h"
8 #include "CesiumGltf/PropertyView.h"
9 #include "CesiumGltf/Sampler.h"
10 #include "CesiumGltf/TextureView.h"
12 #include <CesiumUtility/Assert.h>
86 template <
typename ElementType>
87 ElementType assembleScalarValue(
const gsl::span<uint8_t> bytes) noexcept {
88 if constexpr (std::is_same_v<ElementType, float>) {
90 bytes.size() ==
sizeof(
float) &&
91 "Not enough channel inputs to construct a float.");
92 uint32_t resultAsUint = 0;
93 for (
size_t i = 0; i < bytes.size(); i++) {
94 resultAsUint |=
static_cast<uint32_t
>(bytes[i]) << i * 8;
98 return *
reinterpret_cast<float*
>(&resultAsUint);
101 if constexpr (IsMetadataInteger<ElementType>::value) {
102 using UintType = std::make_unsigned_t<ElementType>;
103 UintType resultAsUint = 0;
104 for (
size_t i = 0; i < bytes.size(); i++) {
105 resultAsUint |=
static_cast<UintType
>(bytes[i]) << i * 8;
109 return *
reinterpret_cast<ElementType*
>(&resultAsUint);
113 template <
typename ElementType>
114 ElementType assembleVecNValue(
const gsl::span<uint8_t> bytes) noexcept {
115 ElementType result = ElementType();
117 const glm::length_t N =
118 getDimensionsFromPropertyType(TypeToPropertyType<ElementType>::value);
119 using T =
typename ElementType::value_type;
122 sizeof(T) <= 2 &&
"Components cannot be larger than two bytes in size.");
124 if constexpr (std::is_same_v<T, int16_t>) {
126 N == 2 &&
"Only vec2s can contain two-byte integer components.");
127 uint16_t x =
static_cast<uint16_t
>(bytes[0]) |
128 (
static_cast<uint16_t
>(bytes[1]) << 8);
129 uint16_t y =
static_cast<uint16_t
>(bytes[2]) |
130 (
static_cast<uint16_t
>(bytes[3]) << 8);
132 result[0] = *
reinterpret_cast<int16_t*
>(&x);
133 result[1] = *
reinterpret_cast<int16_t*
>(&y);
136 if constexpr (std::is_same_v<T, uint16_t>) {
138 N == 2 &&
"Only vec2s can contain two-byte integer components.");
139 result[0] =
static_cast<uint16_t
>(bytes[0]) |
140 (
static_cast<uint16_t
>(bytes[1]) << 8);
141 result[1] =
static_cast<uint16_t
>(bytes[2]) |
142 (
static_cast<uint16_t
>(bytes[3]) << 8);
145 if constexpr (std::is_same_v<T, int8_t>) {
146 for (
size_t i = 0; i < bytes.size(); i++) {
147 result[i] = *
reinterpret_cast<const int8_t*
>(&bytes[i]);
151 if constexpr (std::is_same_v<T, uint8_t>) {
152 for (
size_t i = 0; i < bytes.size(); i++) {
153 result[i] = bytes[i];
160 template <
typename T>
162 assembleArrayValue(
const gsl::span<uint8_t> bytes) noexcept {
163 std::vector<T> result(bytes.size() /
sizeof(T));
165 if constexpr (
sizeof(T) == 2) {
166 for (
int i = 0, b = 0; i < result.size(); i++, b += 2) {
167 using UintType = std::make_unsigned_t<T>;
168 UintType resultAsUint =
static_cast<UintType
>(bytes[b]) |
169 (
static_cast<UintType
>(bytes[b + 1]) << 8);
170 result[i] = *
reinterpret_cast<T*
>(&resultAsUint);
173 for (
size_t i = 0; i < bytes.size(); i++) {
174 result[i] = *
reinterpret_cast<const T*
>(&bytes[i]);
178 return PropertyArrayCopy<T>(std::move(result));
181 template <
typename ElementType>
182 PropertyValueViewToCopy<ElementType>
183 assembleValueFromChannels(
const gsl::span<uint8_t> bytes) noexcept {
185 bytes.size() > 0 &&
"Channel input must have at least one value.");
187 if constexpr (IsMetadataScalar<ElementType>::value) {
188 return assembleScalarValue<ElementType>(bytes);
191 if constexpr (IsMetadataVecN<ElementType>::value) {
192 return assembleVecNValue<ElementType>(bytes);
195 if constexpr (IsMetadataArray<ElementType>::value) {
196 return assembleArrayValue<typename MetadataArrayType<ElementType>::type>(
201 #pragma region Non - normalized property
216 template <
typename ElementType,
bool Normalized = false>
228 template <
typename ElementType>
253 "An empty property view should not be constructed with a valid status");
275 if (!classProperty.defaultProperty) {
303 :
PropertyView<ElementType, false>(classProperty, property),
310 _channels(property.channels),
316 switch (this->getTextureViewStatus()) {
339 _swizzle.reserve(_channels.size());
341 for (
size_t i = 0; i < _channels.size(); ++i) {
342 switch (_channels[i]) {
357 false &&
"A valid channels vector must be passed to the view.");
379 std::optional<PropertyValueViewToCopy<ElementType>>
380 get(
double u,
double v)
const noexcept {
383 return propertyValueViewToCopy(this->defaultValue());
388 if (value == this->noData()) {
389 return propertyValueViewToCopy(this->defaultValue());
391 return transformValue(value, this->offset(), this->scale());
393 return transformArray(
394 propertyValueCopyToView(value),
417 getRaw(
double u,
double v)
const noexcept {
420 "Check the status() first to make sure view is valid");
422 std::vector<uint8_t> sample =
423 this->sampleNearestPixel(u, v, this->_channels);
425 return assembleValueFromChannels<ElementType>(
426 gsl::span(sample.data(), this->_channels.size()));
433 return this->_channels;
439 const std::string&
getSwizzle() const noexcept {
return this->_swizzle; }
442 std::vector<int64_t> _channels;
443 std::string _swizzle;
448 #pragma region Normalized property
457 template <
typename ElementType>
485 "An empty property view should not be constructed with a valid "
508 if (!classProperty.defaultProperty) {
536 :
PropertyView<ElementType, true>(classProperty, property),
543 _channels(property.channels),
549 switch (this->getTextureViewStatus()) {
572 _swizzle.reserve(_channels.size());
573 for (
size_t i = 0; i < _channels.size(); ++i) {
574 switch (_channels[i]) {
589 false &&
"A valid channels vector must be passed to the view.");
612 std::optional<PropertyValueViewToCopy<NormalizedType>>
613 get(
double u,
double v)
const noexcept {
616 return propertyValueViewToCopy(this->defaultValue());
621 if (value == this->noData()) {
622 return propertyValueViewToCopy(this->defaultValue());
624 return transformValue<NormalizedType>(
625 normalize<ElementType>(value),
629 constexpr glm::length_t N = ElementType::length();
630 using T =
typename ElementType::value_type;
631 using NormalizedT =
typename NormalizedType::value_type;
632 return transformValue<glm::vec<N, NormalizedT>>(
633 normalize<N, T>(value),
637 using ArrayElementType =
typename MetadataArrayType<ElementType>::type;
639 return transformNormalizedArray<ArrayElementType>(
640 propertyValueCopyToView(value),
644 constexpr glm::length_t N = ArrayElementType::length();
645 using T =
typename ArrayElementType::value_type;
646 return transformNormalizedVecNArray<N, T>(
647 propertyValueCopyToView(value),
669 getRaw(
double u,
double v)
const noexcept {
672 "Check the status() first to make sure view is valid");
674 std::vector<uint8_t> sample =
675 this->sampleNearestPixel(u, v, this->_channels);
677 return assembleValueFromChannels<ElementType>(
678 gsl::span(sample.data(), this->_channels.size()));
685 return this->_channels;
691 const std::string&
getSwizzle() const noexcept {
return this->_swizzle; }
694 std::vector<int64_t> _channels;
695 std::string _swizzle;
Indicates the status of a property texture property view.
static const int ErrorUnsupportedProperty
This property view is associated with a ClassProperty of an unsupported type.
static const int ErrorChannelsAndTypeMismatch
The channels of this property texture property do not provide the exact number of bytes required by t...
static const int ErrorInvalidImage
This property view does not have a valid image index.
static const int ErrorInvalidChannels
The channels of this property texture property are invalid. Channels must be in the range 0-N,...
static const int ErrorInvalidBytesPerChannel
This property uses an image with multi-byte channels. Only single-byte channels are supported.
static const int ErrorInvalidSampler
This property view does not have a valid sampler index.
static const int ErrorInvalidPropertyTexture
This property view was initialized from an invalid PropertyTexture.
static const int ErrorInvalidTexture
This property view does not have a valid texture index.
static const int ErrorEmptyImage
This property is viewing an empty image.
const std::string & getSwizzle() const noexcept
Gets this property's channels as a swizzle string.
PropertyTexturePropertyView(PropertyViewStatusType status) noexcept
Constructs an invalid instance for an erroneous property.
PropertyTexturePropertyView(const ClassProperty &classProperty) noexcept
Constructs an instance of an empty property that specifies a default value. Although this property ha...
PropertyTexturePropertyView() noexcept
Constructs an invalid instance for a non-existent property.
PropertyValueViewToCopy< ElementType > getRaw(double u, double v) const noexcept
Gets the raw value of the property for the given texture coordinates. The sampler's wrapping mode wil...
const std::vector< int64_t > & getChannels() const noexcept
Gets the channels of this property texture property.
std::optional< PropertyValueViewToCopy< ElementType > > get(double u, double v) const noexcept
Gets the value of the property for the given texture coordinates with all value transforms applied....
PropertyTexturePropertyView(const PropertyTextureProperty &property, const ClassProperty &classProperty, const Sampler &sampler, const ImageAsset &image, const TextureViewOptions &options=TextureViewOptions()) noexcept
Construct a view of the data specified by a PropertyTextureProperty.
const std::string & getSwizzle() const noexcept
Gets this property's channels as a swizzle string.
PropertyTexturePropertyView(const ClassProperty &classProperty) noexcept
Constructs an instance of an empty property that specifies a default value. Although this property ha...
PropertyTexturePropertyView() noexcept
Constructs an invalid instance for a non-existent property.
PropertyValueViewToCopy< ElementType > getRaw(double u, double v) const noexcept
Gets the raw value of the property for the given texture coordinates. The sampler's wrapping mode wil...
std::optional< PropertyValueViewToCopy< NormalizedType > > get(double u, double v) const noexcept
Gets the value of the property for the given texture coordinates with all value transforms applied....
PropertyTexturePropertyView(PropertyViewStatusType status) noexcept
Constructs an invalid instance for an erroneous property.
PropertyTexturePropertyView(const PropertyTextureProperty &property, const ClassProperty &classProperty, const Sampler &sampler, const ImageAsset &image, const TextureViewOptions &options=TextureViewOptions()) noexcept
Construct a view of the data specified by a PropertyTextureProperty.
const std::vector< int64_t > & getChannels() const noexcept
Gets the channels of this property texture property.
A view of the data specified by a PropertyTextureProperty.
Indicates the status of a property view.
static const PropertyViewStatusType Valid
This property view is valid and ready to use.
static const PropertyViewStatusType ErrorNonexistentProperty
This property view is trying to view a property that does not exist.
static const PropertyViewStatusType EmptyPropertyWithDefault
This property view does not contain any data, but specifies a default value. This happens when a clas...
Represents a non-normalized metadata property in EXT_structural_metadata.
Represents a normalized metadata property in EXT_structural_metadata.
Represents a metadata property in EXT_structural_metadata.
Classes for working with glTF models.
@ ErrorEmptyImage
This texture is viewing an empty image.
@ ErrorUninitialized
This texture view has not yet been initialized.
@ Valid
This texture view is valid and ready to use.
@ ErrorInvalidSampler
This texture view does not have a valid sampler index.
@ ErrorInvalidImage
This texture view does not have a valid image index.
@ ErrorInvalidBytesPerChannel
The image for this texture has channels that take up more than a byte. Only single-byte channels are ...
@ ErrorInvalidTexture
This texture view does not have a valid texture index.
std::conditional_t< IsMetadataNumericArray< T >::value, PropertyArrayCopy< typename MetadataArrayType< T >::type >, T > PropertyValueViewToCopy
Transforms a property value type from a view to an equivalent type that owns the data it is viewing....
glTF extension that enables shifting and scaling UV coordinates on a per-texture basis
A 2D image asset, including its pixel data. The image may have mipmaps, and it may be encoded in a GP...
A texture containing property values.
Texture sampler properties for filtering and wrapping modes.
Describes options for constructing a view on a glTF texture.
Convert an integer numeric type to the corresponding representation as a double type....