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>
11#include <CesiumUtility/Assert.h>
92template <
typename ElementType>
94 if constexpr (std::is_same_v<ElementType, float>) {
96 bytes.size() ==
sizeof(
float) &&
97 "Not enough channel inputs to construct a float.");
98 uint32_t resultAsUint = 0;
99 for (
size_t i = 0; i < bytes.size(); i++) {
100 resultAsUint |=
static_cast<uint32_t
>(bytes[i]) << i * 8;
104 return *
reinterpret_cast<float*
>(&resultAsUint);
108 using UintType = std::make_unsigned_t<ElementType>;
109 UintType resultAsUint = 0;
110 for (
size_t i = 0; i < bytes.size(); i++) {
111 resultAsUint |=
static_cast<UintType
>(bytes[i]) << i * 8;
115 return *
reinterpret_cast<ElementType*
>(&resultAsUint);
126template <
typename ElementType>
128 ElementType result = ElementType();
130 const glm::length_t N =
132 using T =
typename ElementType::value_type;
135 sizeof(T) <= 2 &&
"Components cannot be larger than two bytes in size.");
137 if constexpr (std::is_same_v<T, int16_t>) {
139 N == 2 &&
"Only vec2s can contain two-byte integer components.");
140 uint16_t x =
static_cast<uint16_t
>(bytes[0]) |
141 (
static_cast<uint16_t
>(bytes[1]) << 8);
142 uint16_t y =
static_cast<uint16_t
>(bytes[2]) |
143 (
static_cast<uint16_t
>(bytes[3]) << 8);
145 result[0] = *
reinterpret_cast<int16_t*
>(&x);
146 result[1] = *
reinterpret_cast<int16_t*
>(&y);
149 if constexpr (std::is_same_v<T, uint16_t>) {
151 N == 2 &&
"Only vec2s can contain two-byte integer components.");
152 result[0] =
static_cast<uint16_t
>(bytes[0]) |
153 (
static_cast<uint16_t
>(bytes[1]) << 8);
154 result[1] =
static_cast<uint16_t
>(bytes[2]) |
155 (
static_cast<uint16_t
>(bytes[3]) << 8);
158 if constexpr (std::is_same_v<T, int8_t>) {
159 for (
size_t i = 0; i < bytes.size(); i++) {
160 result[i] = *
reinterpret_cast<const int8_t*
>(&bytes[i]);
164 if constexpr (std::is_same_v<T, uint8_t>) {
165 for (
size_t i = 0; i < bytes.size(); i++) {
166 result[i] = bytes[i];
183 std::vector<T> result(bytes.size() /
sizeof(T));
185 if constexpr (
sizeof(T) == 2) {
186 for (
int i = 0, b = 0; i < result.size(); i++, b += 2) {
187 using UintType = std::make_unsigned_t<T>;
188 UintType resultAsUint =
static_cast<UintType
>(bytes[b]) |
189 (
static_cast<UintType
>(bytes[b + 1]) << 8);
190 result[i] = *
reinterpret_cast<T*
>(&resultAsUint);
193 for (
size_t i = 0; i < bytes.size(); i++) {
194 result[i] = *
reinterpret_cast<const T*
>(&bytes[i]);
210template <
typename ElementType>
214 bytes.size() > 0 &&
"Channel input must have at least one value.");
225 return assembleArrayValue<typename MetadataArrayType<ElementType>::type>(
230#pragma region Non - normalized property
245template <
typename ElementType,
bool Normalized = false>
257template <
typename ElementType>
282 "An empty property view should not be constructed with a valid status");
303 if (!classProperty.defaultProperty) {
330 :
PropertyView<ElementType, false>(classProperty, property),
337 _channels(property.channels),
343 switch (this->getTextureViewStatus()) {
366 _swizzle.reserve(_channels.size());
368 for (
size_t i = 0; i < _channels.size(); ++i) {
369 switch (_channels[i]) {
384 false &&
"A valid channels vector must be passed to the view.");
406 std::optional<PropertyValueViewToCopy<ElementType>>
407 get(
double u,
double v)
const noexcept {
410 return propertyValueViewToCopy(this->defaultValue());
415 if (value == this->noData()) {
416 return propertyValueViewToCopy(this->defaultValue());
421 propertyValueCopyToView(value),
444 getRaw(
double u,
double v)
const noexcept {
447 "Check the status() first to make sure view is valid");
449 std::vector<uint8_t> sample =
450 this->sampleNearestPixel(u, v, this->_channels);
453 std::span(sample.data(), this->_channels.size()));
460 return this->_channels;
466 const std::string&
getSwizzle() const noexcept {
return this->_swizzle; }
469 std::vector<int64_t> _channels;
470 std::string _swizzle;
475#pragma region Normalized property
484template <
typename ElementType>
512 "An empty property view should not be constructed with a valid "
535 if (!classProperty.defaultProperty) {
562 :
PropertyView<ElementType, true>(classProperty, property),
569 _channels(property.channels),
575 switch (this->getTextureViewStatus()) {
598 _swizzle.reserve(_channels.size());
599 for (
size_t i = 0; i < _channels.size(); ++i) {
600 switch (_channels[i]) {
615 false &&
"A valid channels vector must be passed to the view.");
638 std::optional<PropertyValueViewToCopy<NormalizedType>>
639 get(
double u,
double v)
const noexcept {
642 return propertyValueViewToCopy(this->defaultValue());
647 if (value == this->noData()) {
648 return propertyValueViewToCopy(this->defaultValue());
655 constexpr glm::length_t N = ElementType::length();
656 using T =
typename ElementType::value_type;
657 using NormalizedT =
typename NormalizedType::value_type;
666 propertyValueCopyToView(value),
670 constexpr glm::length_t N = ArrayElementType::length();
671 using T =
typename ArrayElementType::value_type;
673 propertyValueCopyToView(value),
695 getRaw(
double u,
double v)
const noexcept {
698 "Check the status() first to make sure view is valid");
700 std::vector<uint8_t> sample =
701 this->sampleNearestPixel(u, v, this->_channels);
704 std::span(sample.data(), this->_channels.size()));
711 return this->_channels;
717 const std::string&
getSwizzle() const noexcept {
return this->_swizzle; }
720 std::vector<int64_t> _channels;
721 std::string _swizzle;
A copy of an array element of a PropertyTableProperty or PropertyTextureProperty.
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.
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(PropertyViewStatusType status) noexcept
Constructs an invalid instance for an erroneous 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...
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.
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.
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...
PropertyTexturePropertyView(const ClassProperty &classProperty) noexcept
Constructs an instance of an empty property that specifies a default value. Although this property ha...
const std::string & getSwizzle() const noexcept
Gets this property's channels as a swizzle string.
PropertyTexturePropertyView() noexcept
Constructs an invalid instance for a non-existent property.
PropertyTexturePropertyView(PropertyViewStatusType status) noexcept
Constructs an invalid instance for an erroneous property.
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(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 metadata property in EXT_structural_metadata.
A view into the texture data of a single texture from a Model.
Classes for working with glTF models.
PropertyArrayCopy< glm::vec< N, double > > transformNormalizedVecNArray(const PropertyArrayView< glm::vec< N, T > > &value, const std::optional< PropertyArrayView< glm::vec< N, double > > > &offset, const std::optional< PropertyArrayView< glm::vec< N, double > > > &scale)
Normalizes each element of an array of vectors and transforms them by optional offset and scale facto...
ElementType assembleVecNValue(const std::span< uint8_t > bytes) noexcept
Attempts to obtain a vector value from the given span of bytes.
PropertyArrayCopy< NormalizedType > transformNormalizedArray(const PropertyArrayView< T > &value, const std::optional< PropertyArrayView< NormalizedType > > &offset, const std::optional< PropertyArrayView< NormalizedType > > &scale)
Normalizes each element of an array of values and transforms them by optional offset and scale factor...
T transformValue(const T &value, const std::optional< T > &offset, const std::optional< T > &scale)
Transforms the value by optional offset and scale factors.
double normalize(T value)
Normalizes the given value between [0, 1] if unsigned or [-1, 1] if signed, based on the type's maxim...
@ 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.
PropertyArrayCopy< T > transformArray(const PropertyArrayView< T > &value, const std::optional< PropertyArrayView< T > > &offset, const std::optional< PropertyArrayView< T > > &scale)
Transforms each element of an array of values by optional offset and scale factors....
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....
ElementType assembleScalarValue(const std::span< uint8_t > bytes) noexcept
Attempts to obtain a scalar value from the given span of bytes.
PropertyArrayCopy< T > assembleArrayValue(const std::span< uint8_t > bytes) noexcept
Attempts to obtain an array value from the given span of bytes.
glm::length_t getDimensionsFromPropertyType(PropertyType type)
Obtains the number of dimensions in the given PropertyType.
PropertyValueViewToCopy< ElementType > assembleValueFromChannels(const std::span< uint8_t > bytes) noexcept
Assembles the given type from the provided channel values of sampling a texture.
int32_t PropertyViewStatusType
The type used for fields of PropertyViewStatus.
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....
Convert a C++ type to PropertyType and PropertyComponentType.