diff --git a/src/value-types.cc b/src/value-types.cc index b870284e..ee113355 100644 --- a/src/value-types.cc +++ b/src/value-types.cc @@ -32,7 +32,7 @@ bool IsLerpSupportedType(uint32_t tyid) { // See underlying_type_id to simplify check for Role types(e.g. color3f) #define IS_SUPPORTED_TYPE(__tyid, __ty) \ - if (__tyid == value::TypeTraits<__ty>::underlying_type_id()) return true + if ((__tyid & (~value::TYPE_ID_1D_ARRAY_BIT)) == value::TypeTraits<__ty>::underlying_type_id()) return true IS_SUPPORTED_TYPE(tyid, value::half); IS_SUPPORTED_TYPE(tyid, value::half2); @@ -86,6 +86,15 @@ bool Lerp(const value::Value &a, const value::Value &b, double dt, value::Value result = c; \ ok = true; \ } \ + } else if (tyid == value::TypeTraits>::type_id()) { \ + const std::vector<__ty> *v0 = a.as>(); \ + const std::vector<__ty> *v1 = b.as>(); \ + std::vector<__ty> c; \ + if (v0 && v1) { \ + c = lerp(*v0, *v1, dt); \ + result = c; \ + ok = true; \ + } \ } else DO_LERP(value::half) @@ -137,129 +146,6 @@ bool Lerp(const value::Value &a, const value::Value &b, double dt, value::Value return ok; } - -#if 0 // TODO: Remove -bool Reconstructor::reconstruct(AttribMap &amap) { - err_.clear(); - - staticstruct::Reader r; - -#define CONVERT_TYPE_SCALAR(__ty, __value) \ - case TypeTraits<__ty>::type_id: { \ - __ty *p = reinterpret_cast<__ty *>(__value); \ - staticstruct::Handler<__ty> _h(p); \ - return _h.write(&handler); \ - } - -#define CONVERT_TYPE_1D(__ty, __value) \ - case (TypeTraits<__ty>::type_id | TYPE_ID_1D_ARRAY_BIT): { \ - std::vector<__ty> *p = reinterpret_cast *>(__value); \ - staticstruct::Handler> _h(p); \ - return _h.write(&handler); \ - } - -#define CONVERT_TYPE_2D(__ty, __value) \ - case (TypeTraits<__ty>::type_id | TYPE_ID_2D_ARRAY_BIT): { \ - std::vector> *p = \ - reinterpret_cast> *>(__value); \ - staticstruct::Handler>> _h(p); \ - return _h.write(&handler); \ - } - -#define CONVERT_TYPE_LIST(__FUNC) \ - __FUNC(half, v) \ - __FUNC(half2, v) \ - __FUNC(half3, v) \ - __FUNC(half4, v) \ - __FUNC(int32_t, v) \ - __FUNC(uint32_t, v) \ - __FUNC(int2, v) \ - __FUNC(int3, v) \ - __FUNC(int4, v) \ - __FUNC(uint2, v) \ - __FUNC(uint3, v) \ - __FUNC(uint4, v) \ - __FUNC(int64_t, v) \ - __FUNC(uint64_t, v) \ - __FUNC(float, v) \ - __FUNC(float2, v) \ - __FUNC(float3, v) \ - __FUNC(float4, v) \ - __FUNC(double, v) \ - __FUNC(double2, v) \ - __FUNC(double3, v) \ - __FUNC(double4, v) \ - __FUNC(quath, v) \ - __FUNC(quatf, v) \ - __FUNC(quatd, v) \ - __FUNC(vector3h, v) \ - __FUNC(vector3f, v) \ - __FUNC(vector3d, v) \ - __FUNC(normal3h, v) \ - __FUNC(normal3f, v) \ - __FUNC(normal3d, v) \ - __FUNC(point3h, v) \ - __FUNC(point3f, v) \ - __FUNC(point3d, v) \ - __FUNC(color3f, v) \ - __FUNC(color3d, v) \ - __FUNC(color4f, v) \ - __FUNC(color4d, v) \ - __FUNC(matrix2d, v) \ - __FUNC(matrix3d, v) \ - __FUNC(matrix4d, v) - - bool ret = r.ParseStruct( - &h, - [&amap](std::string key, uint32_t flags, uint32_t user_type_id, - staticstruct::BaseHandler &handler) -> bool { - std::cout << "key = " << key << ", count = " << amap.attribs.count(key) - << "\n"; - - if (!amap.attribs.count(key)) { - if (flags & staticstruct::Flags::Optional) { - return true; - } else { - return false; - } - } - - auto &value = amap.attribs[key]; - if (amap.attribs[key].type_id() == user_type_id) { - void *v = value.value(); - - switch (user_type_id) { - CONVERT_TYPE_SCALAR(bool, v) - - CONVERT_TYPE_LIST(CONVERT_TYPE_SCALAR) - CONVERT_TYPE_LIST(CONVERT_TYPE_1D) - CONVERT_TYPE_LIST(CONVERT_TYPE_2D) - - default: { - std::cerr << "Unsupported type: " << GetTypeName(user_type_id) - << "\n"; - return false; - } - } - } else { - std::cerr << "type: " << amap.attribs[key].type_name() << "(a.k.a " - << amap.attribs[key].underlying_type_name() - << ") expected but got " << GetTypeName(user_type_id) - << " for attribute \"" << key << "\"\n"; - return false; - } - }, - &err_); - - return ret; - -#undef CONVERT_TYPE_SCALAR -#undef CONVERT_TYPE_1D -#undef CONVERT_TYPE_2D -#undef CONVERT_TYPE_LIST -} -#endif - nonstd::optional TryGetTypeName(uint32_t tyid) { MAPBOX_ETERNAL_CONSTEXPR const auto tynamemap = mapbox::eternal::map({ diff --git a/src/value-types.hh b/src/value-types.hh index 7b9364f9..c2d55f3a 100644 --- a/src/value-types.hh +++ b/src/value-types.hh @@ -2191,6 +2191,12 @@ struct LerpTraits { \ static constexpr bool supported() { \ return true; \ } \ +}; \ +template <> \ +struct LerpTraits> { \ + static constexpr bool supported() { \ + return true; \ + } \ }; DEFINE_LERP_TRAIT(value::half) diff --git a/tests/unit/unit-timesamples.cc b/tests/unit/unit-timesamples.cc index 03e069c3..69699681 100644 --- a/tests/unit/unit-timesamples.cc +++ b/tests/unit/unit-timesamples.cc @@ -148,4 +148,44 @@ void timesamples_test(void) { } } + { + primvar::PrimVar pbar; + value::TimeSamples ts; + std::vector ts0 = {{0.0f, 5.0f}}; + std::vector ts1 = {{10.0f, 15.0f}}; + + ts.add_sample(0, ts0); + ts.add_sample(1, ts1); + pbar.set_timesamples(ts); + std::vector default_value = {{100.0f, 200.0f}}; + pbar.set_value(default_value); // default value + + Attribute attr; + attr.set_var(pbar); + + { + std::vector v; + TEST_CHECK(attr.get(value::TimeCode::Default(), &v, value::TimeSampleInterpolationType::Held)); + TEST_CHECK(v.size() == 1); + + TEST_CHECK(math::is_close(v[0][0], 100.0f)); + TEST_CHECK(math::is_close(v[0][1], 200.0f)); + } + + // Linear interpolation + { + std::vector vs; + TEST_CHECK(attr.get(0.0, &vs, value::TimeSampleInterpolationType::Linear)); + TEST_CHECK(vs.size() == 1); + TEST_CHECK(math::is_close(vs[0][0], 0.0f)); + TEST_CHECK(math::is_close(vs[0][1], 5.0f)); + + TEST_CHECK(attr.get(0.5, &vs, value::TimeSampleInterpolationType::Linear)); + TEST_CHECK(vs.size() == 1); + TEST_CHECK(math::is_close(vs[0][0], 5.0f)); + TEST_CHECK(math::is_close(vs[0][1], 10.0f)); + + } + } + }