22#include < djson/json.hpp>
33#include < facade/util/data_provider.hpp>
44#include < facade/util/error.hpp>
5+ #include < facade/util/flex_array.hpp>
56#include < facade/vk/geometry.hpp>
67#include < algorithm>
78#include < bit>
@@ -112,10 +113,43 @@ struct Buffer {
112113 ByteBuffer bytes{};
113114};
114115
115- template <typename T>
116- struct Range {
117- T min{};
118- T max{};
116+ enum class Bound { eFloor, eCeil };
117+
118+ template <Bound B, typename T>
119+ constexpr std::span<double const > limit (T& out, std::span<double const > range) {
120+ if (range.empty ()) { return {}; }
121+ if constexpr (B == Bound::eFloor) {
122+ out = std::min (out, static_cast <T>(range[0 ]));
123+ } else {
124+ out = std::max (out, static_cast <T>(range[0 ]));
125+ }
126+ return range.subspan (1 );
127+ }
128+
129+ template <Bound B, typename T, glm::length_t Dim>
130+ constexpr std::span<double const > limit (glm::vec<Dim, T>& out, std::span<double const > range) {
131+ if (range.empty ()) { return {}; }
132+ assert (range.size () == Dim);
133+ range = limit<B>(out.x , range);
134+ if constexpr (Dim > 1 ) { range = limit<B>(out.y , range); }
135+ if constexpr (Dim > 2 ) { range = limit<B>(out.z , range); }
136+ if constexpr (Dim > 3 ) { range = limit<B>(out.w , range); }
137+ return range;
138+ }
139+
140+ struct ClampRange {
141+ FlexArray<double , 4 > min{};
142+ FlexArray<double , 4 > max{};
143+
144+ constexpr bool active () const { return !min.empty () || !max.empty (); }
145+
146+ template <typename T>
147+ constexpr T operator ()(T const & t) const {
148+ auto ret = t;
149+ limit<Bound::eCeil>(ret, min.span ());
150+ limit<Bound::eFloor>(ret, max.span ());
151+ return ret;
152+ }
119153};
120154
121155struct BufferView {
@@ -154,7 +188,7 @@ struct Accessor {
154188 bool normalized{false };
155189 std::size_t count{};
156190 Type type{};
157- Range<std::array<std::optional< float >, 16 >> ranges {};
191+ ClampRange clamp {};
158192};
159193
160194struct Attributes {
@@ -230,15 +264,19 @@ struct Data {
230264 assert (a.type == Accessor::Type::eScalar);
231265 if (!a.buffer_view ) { return std::vector<T>(a.count ); }
232266 auto const v = view_buffer (*a.buffer_view ).subspan (a.byte_offset );
267+ auto ret = std::vector<T>{};
233268 switch (a.component_type ) {
234- case Accessor::ComponentType::eByte: return convert_vec<T>(vec_from_bytes<std::int8_t >(v, a.count ));
235- case Accessor::ComponentType::eUnsignedByte: return convert_vec<T>(vec_from_bytes<std::uint8_t >(v, a.count ));
236- case Accessor::ComponentType::eShort: return convert_vec<T>(vec_from_bytes<std::int16_t >(v, a.count ));
237- case Accessor::ComponentType::eUnsignedShort: return convert_vec<T>(vec_from_bytes<std::uint16_t >(v, a.count ));
238- case Accessor::ComponentType::eUnsignedInt: return convert_vec<T>(vec_from_bytes<std::uint32_t >(v, a.count ));
239- case Accessor::ComponentType::eFloat: return convert_vec<T>(vec_from_bytes<float >(v, a.count ));
269+ case Accessor::ComponentType::eByte: ret = convert_vec<T>(vec_from_bytes<std::int8_t >(v, a.count )); break ;
270+ case Accessor::ComponentType::eUnsignedByte: ret = convert_vec<T>(vec_from_bytes<std::uint8_t >(v, a.count )); break ;
271+ case Accessor::ComponentType::eShort: ret = convert_vec<T>(vec_from_bytes<std::int16_t >(v, a.count )); break ;
272+ case Accessor::ComponentType::eUnsignedShort: ret = convert_vec<T>(vec_from_bytes<std::uint16_t >(v, a.count )); break ;
273+ case Accessor::ComponentType::eUnsignedInt: ret = convert_vec<T>(vec_from_bytes<std::uint32_t >(v, a.count )); break ;
274+ case Accessor::ComponentType::eFloat: ret = convert_vec<T>(vec_from_bytes<float >(v, a.count )); break ;
240275 }
241- return {};
276+ if (a.clamp .active ()) {
277+ for (auto & t : ret) { t = a.clamp (t); }
278+ }
279+ return ret;
242280 }
243281
244282 template <typename T, glm::length_t Dim>
@@ -249,15 +287,19 @@ struct Data {
249287 assert (Accessor::is_vec_type (a.type , Dim));
250288 if (!a.buffer_view ) { return std::vector<glm::vec<Dim, T>>(a.count ); }
251289 auto const v = view_buffer (*a.buffer_view ).subspan (a.byte_offset );
290+ auto ret = std::vector<glm::vec<Dim, T>>{};
252291 switch (a.component_type ) {
253- case Accessor::ComponentType::eByte: return convert_vec<glm::vec<Dim, T>>(vec_from_bytes<glm::vec<Dim, std::int8_t >>(v, a.count ));
254- case Accessor::ComponentType::eUnsignedByte: return convert_vec<glm::vec<Dim, T>>(vec_from_bytes<glm::vec<Dim, std::uint8_t >>(v, a.count ));
255- case Accessor::ComponentType::eShort: return convert_vec<glm::vec<Dim, T>>(vec_from_bytes<glm::vec<Dim, std::int16_t >>(v, a.count ));
256- case Accessor::ComponentType::eUnsignedShort: return convert_vec<glm::vec<Dim, T>>(vec_from_bytes<glm::vec<Dim, std::uint16_t >>(v, a.count ));
257- case Accessor::ComponentType::eUnsignedInt: return convert_vec<glm::vec<Dim, T>>(vec_from_bytes<glm::vec<Dim, std::uint32_t >>(v, a.count ));
258- case Accessor::ComponentType::eFloat: return convert_vec<glm::vec<Dim, T>>(vec_from_bytes<glm::vec<Dim, float >>(v, a.count ));
292+ case Accessor::ComponentType::eByte: ret = convert_vec<glm::vec<Dim, T>>(vec_from_bytes<glm::vec<Dim, std::int8_t >>(v, a.count )); break ;
293+ case Accessor::ComponentType::eUnsignedByte: ret = convert_vec<glm::vec<Dim, T>>(vec_from_bytes<glm::vec<Dim, std::uint8_t >>(v, a.count )); break ;
294+ case Accessor::ComponentType::eShort: ret = convert_vec<glm::vec<Dim, T>>(vec_from_bytes<glm::vec<Dim, std::int16_t >>(v, a.count )); break ;
295+ case Accessor::ComponentType::eUnsignedShort: ret = convert_vec<glm::vec<Dim, T>>(vec_from_bytes<glm::vec<Dim, std::uint16_t >>(v, a.count )); break ;
296+ case Accessor::ComponentType::eUnsignedInt: ret = convert_vec<glm::vec<Dim, T>>(vec_from_bytes<glm::vec<Dim, std::uint32_t >>(v, a.count )); break ;
297+ case Accessor::ComponentType::eFloat: ret = convert_vec<glm::vec<Dim, T>>(vec_from_bytes<glm::vec<Dim, float >>(v, a.count )); break ;
259298 }
260- return {};
299+ if (a.clamp .active ()) {
300+ for (auto & t : ret) { t = a.clamp (t); }
301+ }
302+ return ret;
261303 }
262304
263305 struct Storage {
@@ -320,7 +362,8 @@ struct Data {
320362 a.byte_offset = json[" byteOffset" ].as <std::size_t >(0U );
321363 a.normalized = json[" normalized" ].as_bool (dj::Boolean{false }).value ;
322364 a.name = json[" name" ].as_string (" (Unnamed)" );
323- // TODO range
365+ for (auto const & min : json[" min" ].array_view ()) { a.clamp .min .insert (min.as_double ()); }
366+ for (auto const & max : json[" max" ].array_view ()) { a.clamp .max .insert (max.as_double ()); }
324367 }
325368
326369 Camera::Orthographic orthographic (dj::Json const & json) const {
0 commit comments