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>
93template <
typename ElementType>
95 if constexpr (std::is_same_v<ElementType, float>) {
97 bytes.size() ==
sizeof(
float) &&
98 "Not enough channel inputs to construct a float.");
99 uint32_t resultAsUint = 0;
100 for (
size_t i = 0; i < bytes.size(); i++) {
101 resultAsUint |=
static_cast<uint32_t
>(bytes[i]) << i * 8;
105 return *
reinterpret_cast<float*
>(&resultAsUint);
109 using UintType = std::make_unsigned_t<ElementType>;
110 UintType resultAsUint = 0;
111 for (
size_t i = 0; i < bytes.size(); i++) {
112 resultAsUint |=
static_cast<UintType
>(bytes[i]) << i * 8;
116 return *
reinterpret_cast<ElementType*
>(&resultAsUint);
127template <
typename ElementType>
129 ElementType result = ElementType();
131 const glm::length_t N =
133 using T =
typename ElementType::value_type;
136 sizeof(T) <= 2 &&
"Components cannot be larger than two bytes in size.");
138 if constexpr (std::is_same_v<T, int16_t>) {
140 N == 2 &&
"Only vec2s can contain two-byte integer components.");
141 uint16_t x =
static_cast<uint16_t
>(bytes[0]) |
142 (
static_cast<uint16_t
>(bytes[1]) << 8);
143 uint16_t y =
static_cast<uint16_t
>(bytes[2]) |
144 (
static_cast<uint16_t
>(bytes[3]) << 8);
146 result[0] = *
reinterpret_cast<int16_t*
>(&x);
147 result[1] = *
reinterpret_cast<int16_t*
>(&y);
150 if constexpr (std::is_same_v<T, uint16_t>) {
152 N == 2 &&
"Only vec2s can contain two-byte integer components.");
153 result[0] =
static_cast<uint16_t
>(bytes[0]) |
154 (
static_cast<uint16_t
>(bytes[1]) << 8);
155 result[1] =
static_cast<uint16_t
>(bytes[2]) |
156 (
static_cast<uint16_t
>(bytes[3]) << 8);
159 if constexpr (std::is_same_v<T, int8_t>) {
160 for (
size_t i = 0; i < bytes.size(); i++) {
161 result[i] = *
reinterpret_cast<const int8_t*
>(&bytes[i]);
165 if constexpr (std::is_same_v<T, uint8_t>) {
166 for (
size_t i = 0; i < bytes.size(); i++) {
167 result[i] = bytes[i];
184 std::vector<T> result(bytes.size() /
sizeof(T));
186 if constexpr (
sizeof(T) == 2) {
187 for (
int i = 0, b = 0; i < result.size(); i++, b += 2) {
188 using UintType = std::make_unsigned_t<T>;
189 UintType resultAsUint =
static_cast<UintType
>(bytes[b]) |
190 (
static_cast<UintType
>(bytes[b + 1]) << 8);
191 result[i] = *
reinterpret_cast<T*
>(&resultAsUint);
194 for (
size_t i = 0; i < bytes.size(); i++) {
195 result[i] = *
reinterpret_cast<const T*
>(&bytes[i]);
211template <
typename ElementType>
215 bytes.size() > 0 &&
"Channel input must have at least one value.");
226 return assembleArrayValue<typename MetadataArrayType<ElementType>::type>(
231#pragma region Non - normalized property
246template <
typename ElementType,
bool Normalized = false>
258template <
typename ElementType>
283 "An empty property view should not be constructed with a valid status");
304 if (!classProperty.defaultProperty) {
331 :
PropertyView<ElementType, false>(classProperty, property),
338 _channels(property.channels),
344 switch (this->getTextureViewStatus()) {
367 _swizzle.reserve(_channels.size());
369 for (
size_t i = 0; i < _channels.size(); ++i) {
370 switch (_channels[i]) {
385 false &&
"A valid channels vector must be passed to the view.");
407 std::optional<PropertyValueViewToCopy<ElementType>>
408 get(
double u,
double v)
const noexcept {
411 return propertyValueViewToCopy(this->defaultValue());
416 if (value == this->noData()) {
417 return propertyValueViewToCopy(this->defaultValue());
422 propertyValueCopyToView(value),
445 getRaw(
double u,
double v)
const noexcept {
448 "Check the status() first to make sure view is valid");
450 std::vector<uint8_t> sample =
451 this->sampleNearestPixel(u, v, this->_channels);
454 std::span(sample.data(), this->_channels.size()));
461 return this->_channels;
467 const std::string&
getSwizzle() const noexcept {
return this->_swizzle; }
470 std::vector<int64_t> _channels;
471 std::string _swizzle;
476#pragma region Normalized property
485template <
typename ElementType>
513 "An empty property view should not be constructed with a valid "
536 if (!classProperty.defaultProperty) {
563 :
PropertyView<ElementType, true>(classProperty, property),
570 _channels(property.channels),
576 switch (this->getTextureViewStatus()) {
599 _swizzle.reserve(_channels.size());
600 for (
size_t i = 0; i < _channels.size(); ++i) {
601 switch (_channels[i]) {
616 false &&
"A valid channels vector must be passed to the view.");
639 std::optional<PropertyValueViewToCopy<NormalizedType>>
640 get(
double u,
double v)
const noexcept {
643 return propertyValueViewToCopy(this->defaultValue());
648 if (value == this->noData()) {
649 return propertyValueViewToCopy(this->defaultValue());
656 constexpr glm::length_t N = ElementType::length();
657 using T =
typename ElementType::value_type;
658 using NormalizedT =
typename NormalizedType::value_type;
667 propertyValueCopyToView(value),
671 constexpr glm::length_t N = ArrayElementType::length();
672 using T =
typename ArrayElementType::value_type;
674 propertyValueCopyToView(value),
696 getRaw(
double u,
double v)
const noexcept {
699 "Check the status() first to make sure view is valid");
701 std::vector<uint8_t> sample =
702 this->sampleNearestPixel(u, v, this->_channels);
705 std::span(sample.data(), this->_channels.size()));
712 return this->_channels;
718 const std::string&
getSwizzle() const noexcept {
return this->_swizzle; }
721 std::vector<int64_t> _channels;
722 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.