@@ -25,7 +25,31 @@ namespace impl
2525template <uint16_t D>
2626NBL_BOOL_CONCEPT Dimension = 1 < D && D < 5 ;
2727
28- // --------------------------------------------------------- MORTON ENCODE/DECODE MASKS ---------------------------------------------------
28+ template<typename T, uint16_t Bits NBL_FUNC_REQUIRES (concepts::Integral<T> && concepts::Scalar<T>)
29+ NBL_CONSTEXPR_FUNC bool verifyAnyBitIntegral (T val)
30+ {
31+ NBL_CONSTEXPR_FUNC_SCOPE_VAR T mask = (~((T (1 ) << Bits) - 1 ));
32+ const bool allZero = ((val & mask) == 0 );
33+ NBL_IF_CONSTEXPR (is_signed_v<T>)
34+ {
35+ const bool allOne = ((val & mask) == mask);
36+ return allZero || allOne;
37+ }
38+ return allZero;
39+ }
40+
41+ template<typename T, uint16_t Dim, uint16_t Bits NBL_FUNC_REQUIRES (concepts::Integral<T> && concepts::Scalar<T>)
42+ NBL_CONSTEXPR_FUNC bool verifyAnyBitIntegralVec (vector <T, Dim> vec)
43+ {
44+ array_get<vector <T, Dim>, T> getter;
45+ [[unroll]]
46+ for (uint16_t i = 0 ; i < Dim; i++)
47+ if (!verifyAnyBitIntegral<T, Bits>(getter (vec, i))) return false ;
48+ return true ;
49+ }
50+
51+
52+ // --------------------------------------------------------- MORTON ENCOE/DECODE MASKS ---------------------------------------------------
2953
3054NBL_CONSTEXPR uint16_t CodingStages = 5 ;
3155
@@ -108,7 +132,8 @@ NBL_HLSL_MORTON_SPECIALIZE_LAST_CODING_MASKS
108132template<uint16_t Dim, uint16_t Bits, typename encode_t NBL_PRIMARY_REQUIRES (Dimension<Dim> && Dim * Bits <= 64 && 8 * sizeof (encode_t) == mpl::max_v<uint64_t, mpl::round_up_to_pot_v<Dim * Bits>, uint64_t (16 )>)
109133struct Transcoder
110134{
111- using decode_t = conditional_t < (Bits > 16 ), vector <uint32_t, Dim>, vector <uint16_t, Dim> >;
135+ using decode_component_t = conditional_t<(Bits > 16 ), uint32_t, uint16_t>;
136+ using decode_t = vector <decode_component_t, Dim>;
112137
113138 template<typename T
114139 NBL_FUNC_REQUIRES (concepts::same_as<T, decode_t> )
@@ -314,6 +339,9 @@ struct code
314339 using storage_t = conditional_t<(TotalBitWidth > 16 ), conditional_t<(TotalBitWidth > 32 ), _uint64_t, uint32_t>, uint16_t>;
315340
316341 using transcoder_t = impl::Transcoder<D, Bits, storage_t>;
342+ using decode_component_t = conditional_t<Signed,
343+ make_signed_t<typename transcoder_t::decode_component_t>,
344+ typename transcoder_t::decode_component_t>;
317345
318346 storage_t value;
319347
@@ -331,10 +359,11 @@ struct code
331359 * @param [in] cartesian Coordinates to encode. Signedness MUST match the signedness of this Morton code class
332360 */
333361 template<typename I>
334- NBL_CONSTEXPR_STATIC enable_if_t<is_integral_v<I> && is_scalar_v<I> && (is_signed_v<I> == Signed && sizeof (I) == sizeof (vector_traits<typename transcoder_t::decode_t>::scalar_type)) , this_t>
362+ NBL_CONSTEXPR_STATIC enable_if_t <concepts::same_as<I, decode_component_t> , this_t>
335363 create (NBL_CONST_REF_ARG (vector <I, D>) cartesian)
336364 {
337365 this_t retVal;
366+ NBL_ASSERT ((impl::verifyAnyBitIntegralVec<I, D, Bits >(cartesian) == true ));
338367 using decode_t = typename transcoder_t::decode_t;
339368 retVal.value = transcoder_t::encode (_static_cast<decode_t>(cartesian));
340369 return retVal;
0 commit comments