8
8
#include " nbl/builtin/hlsl/shapes/aabb.hlsl"
9
9
10
10
#include " nbl/asset/IAsset.h"
11
+ #include " nbl/asset/format/EFormat.h"
11
12
12
13
13
14
namespace nbl ::asset
@@ -48,9 +49,112 @@ class IGeometryBase : public virtual core::IReferenceCounted
48
49
S8_NORM,
49
50
BitCount=4
50
51
};
52
+ //
53
+ static inline EAABBFormat getMatchingAABBFormat (const E_FORMAT attributeFormat)
54
+ {
55
+ if (isBlockCompressionFormat (attributeFormat))
56
+ return EAABBFormat::BitCount;
57
+ if (isFloatingPointFormat (attributeFormat))
58
+ {
59
+ const auto maxVal = getFormatMaxValue<double >(attributeFormat,0 );
60
+ if (maxVal>hlsl::numeric_limits<hlsl::float32_t >::max)
61
+ return EAABBFormat::F64;
62
+ if (maxVal>hlsl::numeric_limits<hlsl::float16_t >::max)
63
+ return EAABBFormat::F32;
64
+ return EAABBFormat::F16;
65
+ }
66
+ else if (isNormalizedFormat (attributeFormat))
67
+ {
68
+ const auto precision = getFormatPrecision<float >(attributeFormat,0 ,0 .f );
69
+ const auto minVal = getFormatMinValue<float >(attributeFormat,0 );
70
+ if (minVal<-0 .f )
71
+ return precision<getFormatPrecision<float >(EF_R8_SNORM,0 ,0 .f ) ? EAABBFormat::S16_NORM:EAABBFormat::S8_NORM;
72
+ else
73
+ return precision<getFormatPrecision<float >(EF_R8_UNORM,0 ,0 .f ) ? EAABBFormat::U16_NORM:EAABBFormat::U8_NORM;
74
+ }
75
+ else if (isIntegerFormat (attributeFormat))
76
+ {
77
+ if (isSignedFormat (attributeFormat))
78
+ {
79
+ const auto maxVal = getFormatMaxValue<int64_t >(attributeFormat,0 );
80
+ if (maxVal>hlsl::numeric_limits<int32_t >::max)
81
+ return EAABBFormat::S64;
82
+ else if (maxVal>hlsl::numeric_limits<int16_t >::max)
83
+ return EAABBFormat::S32;
84
+ else if (maxVal>hlsl::numeric_limits<int8_t >::max)
85
+ return EAABBFormat::S16;
86
+ return EAABBFormat::S8;
87
+ }
88
+ else
89
+ {
90
+ const auto maxVal = getFormatMaxValue<uint64_t >(attributeFormat,0 );
91
+ if (maxVal>hlsl::numeric_limits<uint32_t >::max)
92
+ return EAABBFormat::U64;
93
+ else if (maxVal>hlsl::numeric_limits<uint16_t >::max)
94
+ return EAABBFormat::U32;
95
+ else if (maxVal>hlsl::numeric_limits<uint8_t >::max)
96
+ return EAABBFormat::U16;
97
+ return EAABBFormat::U8;
98
+
99
+ }
100
+ }
101
+ return EAABBFormat::BitCount;
102
+ }
51
103
// using `nbl::hlsl::` concepts instead of `std::` so that `nbl::hlsl::float16_t` can be used
52
104
union SAABBStorage
53
105
{
106
+ template <typename Visitor>
107
+ inline void visit (const EAABBFormat format, Visitor&& visitor)
108
+ {
109
+ switch (format)
110
+ {
111
+ case EAABBFormat::F64:
112
+ visitor (f64 );
113
+ break ;
114
+ case EAABBFormat::U64:
115
+ visitor (u64 );
116
+ break ;
117
+ case EAABBFormat::S64:
118
+ visitor (s64);
119
+ break ;
120
+ case EAABBFormat::F32:
121
+ visitor (f32 );
122
+ break ;
123
+ case EAABBFormat::U32:
124
+ visitor (u32 );
125
+ break ;
126
+ case EAABBFormat::S32:
127
+ visitor (s32);
128
+ break ;
129
+ case EAABBFormat::F16:
130
+ visitor (f16 );
131
+ break ;
132
+ case EAABBFormat::U16: [[fallthrough]];
133
+ case EAABBFormat::U16_NORM:
134
+ visitor (u16 );
135
+ break ;
136
+ case EAABBFormat::S16: [[fallthrough]];
137
+ case EAABBFormat::S16_NORM:
138
+ visitor (s16);
139
+ break ;
140
+ case EAABBFormat::U8: [[fallthrough]];
141
+ case EAABBFormat::U8_NORM:
142
+ visitor (u8 );
143
+ break ;
144
+ case EAABBFormat::S8: [[fallthrough]];
145
+ case EAABBFormat::S8_NORM:
146
+ visitor (s8);
147
+ break ;
148
+ default :
149
+ break ;
150
+ }
151
+ }
152
+ template <typename Visitor>
153
+ inline void visit (const EAABBFormat format, Visitor&& visitor) const
154
+ {
155
+ const_cast <SAABBStorage*>(this )->visit (format,std::forward<Visitor>(visitor));
156
+ }
157
+
54
158
hlsl::shapes::AABB<4 ,hlsl::float64_t > f64 = hlsl::shapes::AABB<4 ,hlsl::float64_t >::create ();
55
159
hlsl::shapes::AABB<4 ,uint64_t > u64 ;
56
160
hlsl::shapes::AABB<4 ,int64_t > s64;
@@ -102,57 +206,9 @@ class IGeometryBase : public virtual core::IReferenceCounted
102
206
103
207
//
104
208
template <typename Visitor>
105
- inline void visitAABB (Visitor& visitor)
106
- {
107
- switch (rangeFormat)
108
- {
109
- case EAABBFormat::F64:
110
- visitor (encodedDataRange.f64 );
111
- break ;
112
- case EAABBFormat::U64:
113
- visitor (encodedDataRange.u64 );
114
- break ;
115
- case EAABBFormat::S64:
116
- visitor (encodedDataRange.s64 );
117
- break ;
118
- case EAABBFormat::F32:
119
- visitor (encodedDataRange.f32 );
120
- break ;
121
- case EAABBFormat::U32:
122
- visitor (encodedDataRange.u32 );
123
- break ;
124
- case EAABBFormat::S32:
125
- visitor (encodedDataRange.s32 );
126
- break ;
127
- case EAABBFormat::F16:
128
- visitor (encodedDataRange.f16 );
129
- break ;
130
- case EAABBFormat::U16: [[fallthrough]];
131
- case EAABBFormat::U16_NORM:
132
- visitor (encodedDataRange.u16 );
133
- break ;
134
- case EAABBFormat::S16: [[fallthrough]];
135
- case EAABBFormat::S16_NORM:
136
- visitor (encodedDataRange.s16 );
137
- break ;
138
- case EAABBFormat::U8: [[fallthrough]];
139
- case EAABBFormat::U8_NORM:
140
- visitor (encodedDataRange.u8 );
141
- break ;
142
- case EAABBFormat::S8: [[fallthrough]];
143
- case EAABBFormat::S8_NORM:
144
- visitor (encodedDataRange.s8 );
145
- break ;
146
- default :
147
- break ;
148
- }
149
- }
209
+ inline void visitAABB (Visitor&& visitor) {encodedDataRange.visit (rangeFormat,std::forward<Visitor>(visitor));}
150
210
template <typename Visitor>
151
- inline void visitAABB (const Visitor& visitor) const
152
- {
153
- auto tmp = [&visitor](const auto & aabb)->void {visitor (aabb);};
154
- const_cast <typename std::decay_t <decltype (*this )>*>(this )->visitAABB (tmp);
155
- }
211
+ inline void visitAABB (Visitor&& visitor) const {encodedDataRange.visit (rangeFormat,std::forward<Visitor>(visitor));}
156
212
157
213
//
158
214
inline void resetRange (const EAABBFormat newFormat)
@@ -188,7 +244,13 @@ class IGeometryBase : public virtual core::IReferenceCounted
188
244
EAABBFormat rangeFormat : int (EAABBFormat::BitCount) = EAABBFormat::F64;
189
245
};
190
246
247
+ virtual EAABBFormat getAABBFormat () const = 0;
191
248
virtual const SAABBStorage& getAABB () const = 0;
249
+ template <typename Visitor>
250
+ inline void visitAABB (Visitor&& visitor) const
251
+ {
252
+ getAABB ().visit (getAABBFormat (),std::forward<Visitor>(visitor));
253
+ }
192
254
193
255
protected:
194
256
virtual inline ~IGeometryBase () = default ;
@@ -224,7 +286,7 @@ class IGeometry : public std::conditional_t<std::is_same_v<BufferType,ICPUBuffer
224
286
explicit inline operator SBufferBinding<const BufferType>() const
225
287
{
226
288
if (*this )
227
- return {.offset =src.offset ,.buffer =smart_refctd_ptr (src.buffer )};
289
+ return {.offset =src.offset ,.buffer =core:: smart_refctd_ptr (src.buffer )};
228
290
return {};
229
291
}
230
292
@@ -242,7 +304,9 @@ class IGeometry : public std::conditional_t<std::is_same_v<BufferType,ICPUBuffer
242
304
template <typename Index=uint32_t , typename U=BufferType> requires (std::is_same_v<U,BufferType> && std::is_same_v<U,ICPUBuffer>)
243
305
inline const void* getPointer(const Index elIx=0 ) const
244
306
{
245
- return const_cast <typename std::decay_t <decltype (*this )>*>(this )->getPointer <U>(elIx);
307
+ if (*this )
308
+ return reinterpret_cast <const uint8_t *>(src.buffer ->getPointer ())+src.offset +elIx*composed.getStride ();
309
+ return nullptr ;
246
310
}
247
311
template <typename Index=uint32_t , typename U=BufferType> requires (std::is_same_v<U,BufferType> && std::is_same_v<U,ICPUBuffer>)
248
312
inline void* getPointer(const Index elIx=0 )
@@ -266,11 +330,16 @@ class IGeometry : public std::conditional_t<std::is_same_v<BufferType,ICPUBuffer
266
330
assert (!isScaledFormat (composed.format )); // handle this by improving the decode functions, not adding workarounds here
267
331
if (decodePixels<code_t >(composed.format ,srcArr,tmp,0 ,0 ))
268
332
{
269
- if (isNormalizedFormat (composed.format ))
333
+ using traits = hlsl::vector_traits<V>;
334
+ const auto range = composed.getRange <hlsl::shapes::AABB<traits::Dimension,typename traits::scalar_type>>();
335
+ for (auto i=0u ; i<traits::Dimension; i++)
270
336
{
271
- using traits = hlsl::vector_traits<V>;
272
- const auto range = composed.getRange <hlsl::shapes::AABB<traits::Dimension,traits::scalar_type>>();
273
- v = v*(range.maxVx -range.minVx )+range.minVx ;
337
+ if (isNormalizedFormat (composed.format ))
338
+ {
339
+ v[i] = tmp[i] * (range.maxVx [i] - range.minVx [i]) + range.minVx [i];
340
+ }
341
+ else
342
+ v[i] = tmp[i];
274
343
}
275
344
return true ;
276
345
}
@@ -290,7 +359,7 @@ class IGeometry : public std::conditional_t<std::is_same_v<BufferType,ICPUBuffer
290
359
using traits = hlsl::vector_traits<V>;
291
360
using code_t = std::conditional_t <hlsl::concepts::FloatingPointVector<V>,hlsl::float64_t ,std::conditional_t <hlsl::concepts::SignedIntVector<V>,int64_t ,uint64_t >>;
292
361
code_t tmp[traits::Dimension];
293
- const auto range = composed.getRange <traits::Dimension,traits::scalar_type>();
362
+ const auto range = composed.getRange <traits::Dimension,typename traits::scalar_type>();
294
363
for (auto i=0u ; i<traits::Dimension; i++)
295
364
{
296
365
if (isNormalizedFormat (composed.format ))
0 commit comments