Skip to content

Commit 2e090a4

Browse files
authored
Incorporate GLTF accessor limits (#65)
1 parent 71764e6 commit 2e090a4

File tree

1 file changed

+63
-20
lines changed

1 file changed

+63
-20
lines changed

lib/scene/src/detail/gltf.cpp

Lines changed: 63 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
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

121155
struct 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

160194
struct 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

Comments
 (0)