cesium-native 0.43.0
Loading...
Searching...
No Matches
PropertyTransformations.h
1#pragma once
2
3#include "CesiumGltf/PropertyArrayView.h"
4#include "CesiumGltf/PropertyTypeTraits.h"
5
6#include <glm/common.hpp>
7
8#include <algorithm>
9#include <cstdint>
10#include <optional>
11
12namespace CesiumGltf {
19template <typename T> double normalize(T value) {
20 constexpr double max = static_cast<double>(std::numeric_limits<T>::max());
21 if constexpr (std::is_signed_v<T>) {
22 return std::max(static_cast<double>(value) / max, -1.0);
23 } else {
24 return static_cast<double>(value) / max;
25 }
26}
27
34template <glm::length_t N, typename T>
35glm::vec<N, double> normalize(glm::vec<N, T> value) {
36 constexpr double max = static_cast<double>(std::numeric_limits<T>::max());
37 if constexpr (std::is_signed_v<T>) {
38 return glm::max(static_cast<glm::vec<N, double>>(value) / max, -1.0);
39 } else {
40 return static_cast<glm::vec<N, double>>(value) / max;
41 }
42}
43
50template <glm::length_t N, typename T>
51glm::mat<N, N, double> normalize(glm::mat<N, N, T> value) {
52 constexpr double max = static_cast<double>(std::numeric_limits<T>::max());
53 // No max() implementation for matrices, so we have to write our own.
54 glm::mat<N, N, double> result;
55 for (glm::length_t i = 0; i < N; i++) {
56 for (glm::length_t j = 0; j < N; j++) {
57 if constexpr (std::is_signed_v<T>) {
58 result[i][j] = glm::max(static_cast<double>(value[i][j]) / max, -1.0);
59 } else {
60 result[i][j] = static_cast<double>(value[i][j]) / max;
61 }
62 }
63 }
64 return result;
65}
66
73template <typename T> T applyScale(const T& value, const T& scale) {
74 if constexpr (IsMetadataMatN<T>::value) {
75 // Do component-wise multiplication instead of actual matrix
76 // multiplication.
77 T matN;
78 constexpr glm::length_t N = T::length();
79 for (glm::length_t i = 0; i < N; i++) {
80 matN[i] = value[i] * scale[i];
81 }
82 return matN;
83 } else {
84 return value * scale;
85 }
86}
87
97template <typename T>
99 const T& value,
100 const std::optional<T>& offset,
101 const std::optional<T>& scale) {
102 T result = value;
103 if (scale) {
104 result = applyScale<T>(result, *scale);
105 }
106
107 if (offset) {
108 result += *offset;
109 }
110
111 return result;
112}
113
125template <typename T>
127 const PropertyArrayView<T>& value,
128 const std::optional<PropertyArrayView<T>>& offset,
129 const std::optional<PropertyArrayView<T>>& scale) {
130 std::vector<T> result(static_cast<size_t>(value.size()));
131 for (int64_t i = 0; i < value.size(); i++) {
132 result[i] = value[i];
133
134 if (scale) {
135 result[i] = applyScale<T>(result[i], (*scale)[i]);
136 }
137
138 if (offset) {
139 result[i] = result[i] + (*offset)[i];
140 }
141 }
142
143 return PropertyArrayCopy(std::move(result));
144}
145
158template <
159 typename T,
160 typename NormalizedType = typename TypeToNormalizedType<T>::type>
162 const PropertyArrayView<T>& value,
163 const std::optional<PropertyArrayView<NormalizedType>>& offset,
164 const std::optional<PropertyArrayView<NormalizedType>>& scale) {
165 std::vector<NormalizedType> result(static_cast<size_t>(value.size()));
166 for (int64_t i = 0; i < value.size(); i++) {
167 result[i] = normalize<T>(value[i]);
168
169 if (scale) {
170 result[i] = result[i] * (*scale)[i];
171 }
172
173 if (offset) {
174 result[i] = result[i] + (*offset)[i];
175 }
176 }
177
178 return PropertyArrayCopy(std::move(result));
179}
180
192template <glm::length_t N, typename T>
194 const PropertyArrayView<glm::vec<N, T>>& value,
195 const std::optional<PropertyArrayView<glm::vec<N, double>>>& offset,
196 const std::optional<PropertyArrayView<glm::vec<N, double>>>& scale) {
197 std::vector<glm::vec<N, double>> result(static_cast<size_t>(value.size()));
198 for (int64_t i = 0; i < value.size(); i++) {
199 result[i] = normalize<N, T>(value[i]);
200
201 if (scale) {
202 result[i] = result[i] * (*scale)[i];
203 }
204
205 if (offset) {
206 result[i] = result[i] + (*offset)[i];
207 }
208 }
209
210 return PropertyArrayCopy(std::move(result));
211}
212
224template <glm::length_t N, typename T>
226 const PropertyArrayView<glm::mat<N, N, T>>& value,
227 const std::optional<PropertyArrayView<glm::mat<N, N, double>>>& offset,
228 const std::optional<PropertyArrayView<glm::mat<N, N, double>>>& scale) {
229 std::vector<glm::mat<N, N, double>> result(static_cast<size_t>(value.size()));
230 for (int64_t i = 0; i < value.size(); i++) {
231 result[i] = normalize<N, T>(value[i]);
232
233 if (scale) {
234 result[i] = applyScale<glm::mat<N, N, double>>(result[i], (*scale)[i]);
235 }
236
237 if (offset) {
238 result[i] = result[i] + (*offset)[i];
239 }
240 }
241
242 return PropertyArrayCopy(std::move(result));
243}
244} // namespace CesiumGltf
A copy of an array element of a PropertyTableProperty or PropertyTextureProperty.
A view on an array element of a PropertyTableProperty or PropertyTextureProperty.
int64_t size() const noexcept
The number of elements in this array.
Classes for working with glTF models.
T applyScale(const T &value, const T &scale)
Multiplies each component of the value by the given scale factor.
PropertyArrayCopy< glm::mat< N, N, double > > transformNormalizedMatNArray(const PropertyArrayView< glm::mat< N, N, T > > &value, const std::optional< PropertyArrayView< glm::mat< N, N, double > > > &offset, const std::optional< PropertyArrayView< glm::mat< N, N, double > > > &scale)
Normalizes each element of an array of matrices and transforms them by optional offset and scale fact...
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...
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...
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....
Check if a C++ type can be represented as a matN type.