3#include <CesiumGltf/KhrTextureTransform.h>
4#include <CesiumGltf/PropertyTextureProperty.h>
5#include <CesiumGltf/PropertyTransformations.h>
6#include <CesiumGltf/PropertyTypeTraits.h>
7#include <CesiumGltf/PropertyView.h>
8#include <CesiumGltf/Sampler.h>
9#include <CesiumGltf/TextureView.h>
10#include <CesiumImage/ImageAsset.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;
108 std::memcpy(&resultAsFloat, &resultAsUint,
sizeof(
float));
109 return resultAsFloat;
113 using UintType = std::make_unsigned_t<ElementType>;
114 UintType resultAsUint = 0;
115 for (
size_t i = 0; i < bytes.size(); i++) {
117 static_cast<UintType
>(
static_cast<UintType
>(bytes[i]) << i * 8);
121 return *
reinterpret_cast<ElementType*
>(&resultAsUint);
132template <
typename ElementType>
134 ElementType result = ElementType();
136 [[maybe_unused]]
constexpr glm::length_t N =
138 using T =
typename ElementType::value_type;
141 sizeof(T) <= 2 &&
"Components cannot be larger than two bytes in size.");
143 if constexpr (std::is_same_v<T, int16_t>) {
145 N == 2 &&
"Only vec2s can contain two-byte integer components.");
146 uint16_t x =
static_cast<uint16_t
>(bytes[0]) |
147 static_cast<uint16_t
>(
static_cast<uint16_t
>(bytes[1]) << 8);
148 uint16_t y =
static_cast<uint16_t
>(bytes[2]) |
149 static_cast<uint16_t
>(
static_cast<uint16_t
>(bytes[3]) << 8);
151 result[0] = *
reinterpret_cast<int16_t*
>(&x);
152 result[1] = *
reinterpret_cast<int16_t*
>(&y);
155 if constexpr (std::is_same_v<T, uint16_t>) {
157 N == 2 &&
"Only vec2s can contain two-byte integer components.");
158 result[0] =
static_cast<uint16_t
>(bytes[0]) |
159 static_cast<uint16_t
>(
static_cast<uint16_t
>(bytes[1]) << 8);
160 result[1] =
static_cast<uint16_t
>(bytes[2]) |
161 static_cast<uint16_t
>(
static_cast<uint16_t
>(bytes[3]) << 8);
164 if constexpr (std::is_same_v<T, int8_t>) {
165 for (
size_t i = 0; i < bytes.size(); i++) {
166 result[int32_t(i)] = *
reinterpret_cast<const int8_t*
>(&bytes[i]);
170 if constexpr (std::is_same_v<T, uint8_t>) {
171 for (
size_t i = 0; i < bytes.size(); i++) {
172 result[int32_t(i)] = bytes[i];
189 std::vector<T> result(bytes.size() /
sizeof(T));
191 if constexpr (
sizeof(T) == 2) {
192 for (
size_t i = 0, b = 0; i < result.size(); i++, b += 2) {
193 using UintType = std::make_unsigned_t<T>;
194 UintType resultAsUint =
195 static_cast<UintType
>(bytes[b]) |
196 static_cast<UintType
>(
static_cast<UintType
>(bytes[b + 1]) << 8);
197 result[i] = *
reinterpret_cast<T*
>(&resultAsUint);
200 for (
size_t i = 0; i < bytes.size(); i++) {
201 result[i] = *
reinterpret_cast<const T*
>(&bytes[i]);
217template <
typename ElementType>
221 bytes.size() > 0 &&
"Channel input must have at least one value.");
237#pragma region Non - normalized property
252template <
typename ElementType,
bool Normalized = false>
264template <
typename ElementType>
289 "An empty property view should not be constructed with a valid status");
310 if (!classProperty.defaultProperty) {
338 :
PropertyView<ElementType, false>(classProperty, property),
345 _channels(property.channels),
374 _swizzle.reserve(_channels.size());
376 for (
size_t i = 0; i < _channels.size(); ++i) {
377 switch (_channels[i]) {
392 false &&
"A valid channels vector must be passed to the view.");
426 _channels(property.channels),
455 _swizzle.reserve(_channels.size());
457 for (
size_t i = 0; i < _channels.size(); ++i) {
458 switch (_channels[i]) {
473 false &&
"A valid channels vector must be passed to the view.");
495 std::optional<PropertyValueViewToCopy<ElementType>>
496 get(
double u,
double v)
const noexcept {
504 if (value == this->
noData()) {
510 propertyValueCopyToView(value),
533 getRaw(
double u,
double v)
const noexcept {
536 "Check the status() first to make sure view is valid");
538 std::vector<uint8_t> sample =
542 std::span(sample.data(), this->_channels.size()));
549 return this->_channels;
555 const std::string&
getSwizzle() const noexcept {
return this->_swizzle; }
558 std::vector<int64_t> _channels;
559 std::string _swizzle;
564#pragma region Normalized property
573template <
typename ElementType>
601 "An empty property view should not be constructed with a valid "
652 :
PropertyView<ElementType, true>(classProperty, property),
659 _channels(property.channels),
688 _swizzle.reserve(_channels.size());
689 for (
size_t i = 0; i < _channels.size(); ++i) {
690 switch (_channels[i]) {
705 false &&
"A valid channels vector must be passed to the view.");
728 std::optional<PropertyValueViewToCopy<NormalizedType>>
729 get(
double u,
double v)
const noexcept {
737 if (value == this->
noData()) {
745 constexpr glm::length_t N = ElementType::length();
746 using T =
typename ElementType::value_type;
747 using NormalizedT =
typename NormalizedType::value_type;
756 propertyValueCopyToView(value),
760 constexpr glm::length_t N = ArrayElementType::length();
761 using T =
typename ArrayElementType::value_type;
763 propertyValueCopyToView(value),
785 getRaw(
double u,
double v)
const noexcept {
788 "Check the status() first to make sure view is valid");
790 std::vector<uint8_t> sample =
794 std::span(sample.data(), this->_channels.size()));
801 return this->_channels;
807 const std::string&
getSwizzle() const noexcept {
return this->_swizzle; }
810 std::vector<int64_t> _channels;
811 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.
PropertyTexturePropertyView(const PropertyTextureProperty &property, const ClassProperty &classProperty, const CesiumGltf::Enum *pEnumDefinition, const Sampler &sampler, const CesiumImage::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.
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(const PropertyTextureProperty &property, const ClassProperty &classProperty, const Sampler &sampler, const CesiumImage::ImageAsset &image, const TextureViewOptions &options=TextureViewOptions()) noexcept
Construct a view of the data specified by a PropertyTextureProperty.
PropertyTexturePropertyView() noexcept
Constructs an invalid instance for a non-existent property.
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(const PropertyTextureProperty &property, const ClassProperty &classProperty, const Sampler &sampler, const CesiumImage::ImageAsset &image, const TextureViewOptions &options=TextureViewOptions()) noexcept
Construct a view of the data specified by a PropertyTextureProperty.
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....
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...
std::optional< ElementType > offset() const noexcept
Gets the offset to apply to property values. Only applicable to SCALAR, VECN, and MATN types when the...
std::optional< ElementType > scale() const noexcept
Gets the scale to apply to property values. Only applicable to SCALAR, VECN, and MATN types when the ...
std::optional< ElementType > defaultValue() const noexcept
Gets the default value to use when encountering a "no data" value or an omitted property....
PropertyViewStatusType _status
Indicates the status of a property view.
PropertyViewStatusType status() const noexcept
Gets the status of this property view, indicating whether an error occurred.
std::optional< ElementType > noData() const noexcept
Gets the "no data" value, i.e., the value representing missing data in the property wherever it appea...
PropertyView()
Constructs an empty property instance.
std::optional< ElementType > noData() const noexcept
Constructs an empty property instance. false>noData
PropertyViewStatusType _status
Indicates the status of a property view.
std::optional< NormalizedType > scale() const noexcept
Constructs an empty property instance. false>scale
PropertyView()
Constructs an empty property instance.
std::optional< NormalizedType > defaultValue() const noexcept
Constructs an empty property instance. false>defaultValue
PropertyViewStatusType status() const noexcept
Constructs an empty property instance. false>status
std::optional< NormalizedType > offset() const noexcept
Constructs an empty property instance. false>offset
TextureViewStatus getTextureViewStatus() const noexcept
Get the status of this texture view.
TextureView() noexcept
Constructs an empty, uninitialized texture view.
std::vector< uint8_t > sampleNearestPixel(double u, double v, const std::vector< int64_t > &channels) const noexcept
Samples the image at the specified texture coordinates using NEAREST pixel filtering,...
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.
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.
std::optional< CesiumUtility::JsonValue > defaultProperty
A default value to use when encountering a noData value or an omitted property. The value is given in...
This class is not meant to be instantiated directly. Use Enum instead.
glTF extension that enables shifting and scaling UV coordinates on a per-texture basis
A texture containing property values.
Texture sampler properties for filtering and wrapping modes.
Describes options for constructing a view on a glTF texture.
The number of dimensions that this type contains.
Convert an integer numeric type to the corresponding representation as a double type....
A 2D image asset, including its pixel data. The image may have mipmaps, and it may be encoded in a GP...