@@ -108,18 +108,21 @@ NBL_HLSL_MORTON_SPECIALIZE_LAST_CODING_MASKS
108108template<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 )>)
109109struct Transcoder
110110{
111- template<typename decode_t = conditional_t<(Bits > 16 ), vector <uint32_t, Dim>, vector <uint16_t, Dim> >
112- NBL_FUNC_REQUIRES (concepts::IntVector<decode_t> && 8 * sizeof (typename vector_traits<decode_t>::scalar_type) >= Bits)
111+ using decode_t = conditional_t < (Bits > 16 ), vector <uint32_t, Dim>, vector <uint16_t, Dim> >;
112+
113+ template<typename T
114+ NBL_FUNC_REQUIRES (concepts::same_as<T, decode_t> )
113115 /**
114116 * @brief Interleaves each coordinate with `Dim - 1` zeros inbetween each bit, and left-shifts each by their coordinate index
115117 *
116118 * @param [in] decodedValue Cartesian coordinates to interleave and shift
117119 */
118- NBL_CONSTEXPR_STATIC portable_vector_t<encode_t, Dim> interleaveShift (NBL_CONST_REF_ARG (decode_t ) decodedValue)
120+ NBL_CONSTEXPR_STATIC portable_vector_t<encode_t, Dim> interleaveShift (NBL_CONST_REF_ARG (T ) decodedValue)
119121 {
120122 left_shift_operator<portable_vector_t<encode_t, Dim> > leftShift;
121123 portable_vector_t<encode_t, Dim> interleaved = _static_cast<portable_vector_t<encode_t, Dim> >(decodedValue) & coding_mask_v<Dim, Bits, CodingStages, encode_t>;
122124
125+ // Read this to understand how interleaving and spreading bits works https://fgiesen.wordpress.com/2009/12/13/decoding-morton-codes/
123126 #define ENCODE_LOOP_ITERATION (I) NBL_IF_CONSTEXPR (Bits > (uint16_t (1 ) << I))\
124127 {\
125128 interleaved = interleaved | leftShift (interleaved, (uint16_t (1 ) << I) * (Dim - 1 ));\
@@ -137,15 +140,15 @@ struct Transcoder
137140 return leftShift (interleaved, truncate<vector <uint16_t, Dim> >(vector <uint16_t, 4 >(0 , 1 , 2 , 3 )));
138141 }
139142
140- template<typename decode_t = conditional_t<(Bits > 16 ), vector <uint32_t, Dim>, vector <uint16_t, Dim> > >
143+ template<typename T >
141144 /**
142145 * @brief Encodes a vector of cartesian coordinates as a Morton code
143146 *
144147 * @param [in] decodedValue Cartesian coordinates to encode
145148 */
146- NBL_CONSTEXPR_STATIC encode_t encode (NBL_CONST_REF_ARG (decode_t ) decodedValue)
149+ NBL_CONSTEXPR_STATIC encode_t encode (NBL_CONST_REF_ARG (T ) decodedValue)
147150 {
148- const portable_vector_t<encode_t, Dim> interleaveShifted = interleaveShift<decode_t >(decodedValue);
151+ const portable_vector_t<encode_t, Dim> interleaveShifted = interleaveShift<T >(decodedValue);
149152
150153 array_get<portable_vector_t<encode_t, Dim>, encode_t> getter;
151154 encode_t encoded = getter (interleaveShifted, 0 );
@@ -157,8 +160,6 @@ struct Transcoder
157160 return encoded;
158161 }
159162
160- template<typename decode_t = conditional_t<(Bits > 16 ), vector <uint32_t, Dim>, vector <uint16_t, Dim> >
161- NBL_FUNC_REQUIRES (concepts::IntVector<decode_t> && 8 * sizeof (typename vector_traits<decode_t>::scalar_type) >= Bits)
162163 /**
163164 * @brief Decodes a Morton code back to a vector of cartesian coordinates
164165 *
@@ -231,7 +232,8 @@ struct Equal<Signed, Bits, D, storage_t, false>
231232 NBL_CONSTEXPR_STATIC vector <bool , D> __call (NBL_CONST_REF_ARG (storage_t) value, NBL_CONST_REF_ARG (vector <I, D>) rhs)
232233 {
233234 using right_sign_t = conditional_t<Signed, make_signed_t<storage_t>, make_unsigned_t<storage_t> >;
234- const portable_vector_t<right_sign_t, D> interleaved = _static_cast<portable_vector_t<right_sign_t, D> >(Transcoder<D, Bits, storage_t>::interleaveShift (rhs));
235+ using transcoder_t = Transcoder<D, Bits, storage_t>;
236+ const portable_vector_t<right_sign_t, D> interleaved = _static_cast<portable_vector_t<right_sign_t, D> >(transcoder_t::interleaveShift (_static_cast<typename transcoder_t::decode_t>(rhs)));
235237 return Equal <Signed, Bits, D, storage_t, true >::template __call<right_sign_t>(value, interleaved);
236238 }
237239};
@@ -281,7 +283,8 @@ struct BaseComparison<Signed, Bits, D, storage_t, false, ComparisonOp>
281283 NBL_CONSTEXPR_STATIC vector <bool , D> __call (NBL_CONST_REF_ARG (storage_t) value, NBL_CONST_REF_ARG (vector <I, D>) rhs)
282284 {
283285 using right_sign_t = conditional_t<Signed, make_signed_t<storage_t>, make_unsigned_t<storage_t> >;
284- const portable_vector_t<right_sign_t, D> interleaved = _static_cast<portable_vector_t<right_sign_t, D> >(Transcoder<D, Bits, storage_t>::interleaveShift (rhs));
286+ using transcoder_t = Transcoder<D, Bits, storage_t>;
287+ const portable_vector_t<right_sign_t, D> interleaved = _static_cast<portable_vector_t<right_sign_t, D> >(transcoder_t::interleaveShift (_static_cast<typename transcoder_t::decode_t>(rhs)));
285288 return BaseComparison<Signed, Bits, D, storage_t, true , ComparisonOp>::template __call<right_sign_t>(value, interleaved);
286289 }
287290};
@@ -309,6 +312,8 @@ struct code
309312 using this_signed_t = code<true , Bits, D, _uint64_t>;
310313 NBL_CONSTEXPR_STATIC uint16_t TotalBitWidth = D * Bits;
311314 using storage_t = conditional_t<(TotalBitWidth > 16 ), conditional_t<(TotalBitWidth > 32 ), _uint64_t, uint32_t>, uint16_t>;
315+
316+ using transcoder_t = impl::Transcoder<D, Bits, storage_t>;
312317
313318 storage_t value;
314319
@@ -326,11 +331,12 @@ struct code
326331 * @param [in] cartesian Coordinates to encode. Signedness MUST match the signedness of this Morton code class
327332 */
328333 template<typename I>
329- NBL_CONSTEXPR_STATIC enable_if_t<is_integral_v<I> && is_scalar_v<I> && (is_signed_v<I> == Signed), this_t>
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>
330335 create (NBL_CONST_REF_ARG (vector <I, D>) cartesian)
331336 {
332337 this_t retVal;
333- retVal.value = impl::Transcoder<D, Bits, storage_t>::encode (cartesian);
338+ using decode_t = typename transcoder_t::decode_t;
339+ retVal.value = transcoder_t::encode (_static_cast<decode_t>(cartesian));
334340 return retVal;
335341 }
336342
0 commit comments