Skip to content

Commit 925023e

Browse files
committed
adjust to comments
1 parent 08a83fd commit 925023e

20 files changed

Lines changed: 458 additions & 335 deletions

include/nbl/builtin/hlsl/array_accessors.hlsl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ struct array_set
2424
arr[index] = val;
2525
}
2626
};
27+
2728
}
2829
}
2930

30-
#endif
31+
#endif

include/nbl/builtin/hlsl/cpp_compat/basic.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ struct add_pointer
8484

8585
#endif
8686

87+
88+
8789
namespace nbl
8890
{
8991
namespace hlsl

include/nbl/builtin/hlsl/ies/profile.hlsl

Lines changed: 22 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#define _NBL_BUILTIN_HLSL_IES_PROFILE_INCLUDED_
77

88
#include "nbl/builtin/hlsl/cpp_compat.hlsl"
9+
#include "nbl/builtin/hlsl/cpp_compat/basic.h"
910

1011
namespace nbl
1112
{
@@ -16,31 +17,21 @@ namespace ies
1617

1718
struct ProfileProperties
1819
{
19-
//! max 16K resolution
20-
NBL_CONSTEXPR_STATIC_INLINE uint32_t CDC_MAX_TEXTURE_WIDTH = 15360u;
21-
NBL_CONSTEXPR_STATIC_INLINE uint32_t CDC_MAX_TEXTURE_HEIGHT = 8640u;
22-
23-
// TODO: This constraint is hack because the mitsuba loader and its material compiler use Virtual Texturing, and there's some bug with IES not sampling sub 128x128 mip levels
24-
// don't want to spend time to fix this since we'll be using descriptor indexing for the next iteration
25-
NBL_CONSTEXPR_STATIC_INLINE uint32_t CDC_MIN_TEXTURE_WIDTH = 128u;
26-
NBL_CONSTEXPR_STATIC_INLINE uint32_t CDC_MIN_TEXTURE_HEIGHT = 128u;
27-
28-
NBL_CONSTEXPR_STATIC_INLINE uint32_t CDC_DEFAULT_TEXTURE_WIDTH = 1024u;
29-
NBL_CONSTEXPR_STATIC_INLINE uint32_t CDC_DEFAULT_TEXTURE_HEIGHT = 1024u;
30-
31-
NBL_CONSTEXPR_STATIC_INLINE float32_t MAX_VANGLE = 180.f;
32-
NBL_CONSTEXPR_STATIC_INLINE float32_t MAX_HANGLE = 360.f;
20+
NBL_CONSTEXPR_STATIC_INLINE float32_t MaxVAngleDegrees = 180.f;
21+
NBL_CONSTEXPR_STATIC_INLINE float32_t MaxHAngleDegrees = 360.f;
3322

3423
// TODO: could change to uint8_t once we get implemented
3524
// https://github.com/microsoft/hlsl-specs/pull/538
36-
using packed_flags_t = uint16_t;
25+
using packed_flags_t = uint32_t;
3726

38-
NBL_CONSTEXPR_STATIC_INLINE packed_flags_t VERSION_BITS = 2u;
39-
NBL_CONSTEXPR_STATIC_INLINE packed_flags_t TYPE_BITS = 2u;
40-
NBL_CONSTEXPR_STATIC_INLINE packed_flags_t SYMM_BITS = 3u;
41-
NBL_CONSTEXPR_STATIC_INLINE packed_flags_t VERSION_MASK = (packed_flags_t(1u) << VERSION_BITS) - packed_flags_t(1u);
42-
NBL_CONSTEXPR_STATIC_INLINE packed_flags_t TYPE_MASK = (packed_flags_t(1u) << TYPE_BITS) - packed_flags_t(1u);
43-
NBL_CONSTEXPR_STATIC_INLINE packed_flags_t SYMM_MASK = (packed_flags_t(1u) << SYMM_BITS) - packed_flags_t(1u);
27+
NBL_CONSTEXPR_STATIC_INLINE packed_flags_t VersionBits = 2u;
28+
NBL_CONSTEXPR_STATIC_INLINE packed_flags_t TypeBits = 2u;
29+
NBL_CONSTEXPR_STATIC_INLINE packed_flags_t SymmetryBits = 3u;
30+
NBL_CONSTEXPR_STATIC_INLINE packed_flags_t VersionMask = (packed_flags_t(1u) << VersionBits) - packed_flags_t(1u);
31+
NBL_CONSTEXPR_STATIC_INLINE packed_flags_t TypeMask = (packed_flags_t(1u) << TypeBits) - packed_flags_t(1u);
32+
NBL_CONSTEXPR_STATIC_INLINE packed_flags_t SymmetryMask = (packed_flags_t(1u) << SymmetryBits) - packed_flags_t(1u);
33+
NBL_CONSTEXPR_STATIC_INLINE packed_flags_t TypeShift = VersionBits;
34+
NBL_CONSTEXPR_STATIC_INLINE packed_flags_t SymmetryShift = VersionBits + TypeBits;
4435

4536
enum Version : packed_flags_t
4637
{
@@ -68,39 +59,35 @@ struct ProfileProperties
6859

6960
Version getVersion() NBL_CONST_MEMBER_FUNC
7061
{
71-
return (Version)( packed & VERSION_MASK );
62+
return (Version)(packed & VersionMask);
7263
}
7364

7465
PhotometricType getType() NBL_CONST_MEMBER_FUNC
7566
{
76-
const packed_flags_t shift = VERSION_BITS;
77-
return (PhotometricType)((packed >> shift) & TYPE_MASK);
67+
return (PhotometricType)((packed >> TypeShift) & TypeMask);
7868
}
7969

8070
LuminairePlanesSymmetry getSymmetry() NBL_CONST_MEMBER_FUNC
8171
{
82-
const packed_flags_t shift = VERSION_BITS + TYPE_BITS;
83-
return (LuminairePlanesSymmetry)((packed >> shift) & SYMM_MASK);
72+
return (LuminairePlanesSymmetry)((packed >> SymmetryShift) & SymmetryMask);
8473
}
8574

8675
void setVersion(Version v)
8776
{
88-
packed_flags_t vBits = (packed_flags_t)(v) & VERSION_MASK;
89-
packed = (packed & ~VERSION_MASK) | vBits;
77+
packed_flags_t vBits = (packed_flags_t)(v) & VersionMask;
78+
packed = (packed & ~VersionMask) | vBits;
9079
}
9180

9281
void setType(PhotometricType t)
9382
{
94-
const packed_flags_t shift = VERSION_BITS;
95-
packed_flags_t tBits = ((packed_flags_t)(t) & TYPE_MASK) << shift;
96-
packed = (packed & ~(TYPE_MASK << shift)) | tBits;
83+
packed_flags_t tBits = ((packed_flags_t)(t) & TypeMask) << TypeShift;
84+
packed = (packed & ~(TypeMask << TypeShift)) | tBits;
9785
}
9886

9987
void setSymmetry(LuminairePlanesSymmetry s)
10088
{
101-
const packed_flags_t shift = VERSION_BITS + TYPE_BITS;
102-
packed_flags_t sBits = ((packed_flags_t)(s) & SYMM_MASK) << shift;
103-
packed = (packed & ~(SYMM_MASK << shift)) | sBits;
89+
packed_flags_t sBits = ((packed_flags_t)(s) & SymmetryMask) << SymmetryShift;
90+
packed = (packed & ~(SymmetryMask << SymmetryShift)) | sBits;
10491
}
10592

10693
float32_t maxCandelaValue; //! Max candela sample value
@@ -111,6 +98,7 @@ struct ProfileProperties
11198
};
11299

113100
}
101+
114102
}
115103
}
116104

include/nbl/builtin/hlsl/ies/sampler.hlsl

Lines changed: 97 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,19 @@
66
#define _NBL_BUILTIN_HLSL_IES_SAMPLER_INCLUDED_
77

88
#include "nbl/builtin/hlsl/cpp_compat.hlsl"
9+
#include "nbl/builtin/hlsl/limits.hlsl"
10+
#include "nbl/builtin/hlsl/bit.hlsl"
11+
#include "nbl/builtin/hlsl/algorithm.hlsl"
912
#include "nbl/builtin/hlsl/math/polar.hlsl"
1013
#include "nbl/builtin/hlsl/math/octahedral.hlsl"
1114
#include "nbl/builtin/hlsl/concepts.hlsl"
1215
#include "nbl/builtin/hlsl/ies/profile.hlsl"
1316

14-
namespace nbl
17+
namespace nbl
1518
{
16-
namespace hlsl
19+
namespace hlsl
1720
{
18-
namespace ies
21+
namespace ies
1922
{
2023
namespace concepts
2124
{
@@ -27,26 +30,26 @@ NBL_CONCEPT_BEGIN(1)
2730
#define accessor NBL_CONCEPT_PARAM_T NBL_CONCEPT_PARAM_0
2831
#define req_key_t uint32_t
2932
#define req_key_t2 uint32_t2
30-
#define req_value_t float32_t
33+
#define req_angle_t float32_t
34+
#define req_candela_t float32_t
3135
NBL_CONCEPT_END(
32-
((NBL_CONCEPT_REQ_TYPE)(accessor_t::key_t))
33-
((NBL_CONCEPT_REQ_TYPE)(accessor_t::key_t2))
34-
((NBL_CONCEPT_REQ_TYPE)(accessor_t::value_t))
35-
((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((req_key_t(0)), is_same_v, typename accessor_t::key_t))
36-
((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((req_key_t2(0, 0)), is_same_v, typename accessor_t::key_t2))
37-
((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((req_value_t(0)), is_same_v, typename accessor_t::value_t))
36+
((NBL_CONCEPT_REQ_TYPE)(accessor_t::angle_t))
37+
((NBL_CONCEPT_REQ_TYPE)(accessor_t::candela_t))
38+
((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((req_angle_t(0)), is_same_v, typename accessor_t::angle_t))
39+
((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((req_candela_t(0)), is_same_v, typename accessor_t::candela_t))
3840

41+
((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((accessor.getProperties()), is_same_v, ProfileProperties))
42+
((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((accessor.value(req_key_t2(0, 0))), is_same_v, typename accessor_t::candela_t))
3943
((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((accessor.vAnglesCount()), is_same_v, req_key_t))
4044
((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((accessor.hAnglesCount()), is_same_v, req_key_t))
41-
((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((accessor.getProperties()), is_same_v, ProfileProperties))
42-
((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((accessor.template vAngle<req_key_t>((req_key_t)0)), is_same_v, req_value_t))
43-
((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((accessor.template hAngle<req_key_t>((req_key_t)0)), is_same_v, req_value_t))
44-
((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((accessor.template value<req_key_t2>((req_key_t2)0)), is_same_v, req_value_t))
45+
((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((accessor.vAngle(req_key_t(0))), is_same_v, typename accessor_t::angle_t))
46+
((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((accessor.hAngle(req_key_t(0))), is_same_v, typename accessor_t::angle_t))
4547
);
4648
#undef accessor
4749
#undef req_key_t
4850
#undef req_key_t2
49-
#undef req_value_t
51+
#undef req_angle_t
52+
#undef req_candela_t
5053
#include <nbl/builtin/hlsl/concepts/__end.hlsl>
5154

5255
template<typename accessor_t>
@@ -57,109 +60,106 @@ template<typename Accessor NBL_FUNC_REQUIRES(concepts::IsIESAccessor<Accessor>)
5760
struct CandelaSampler
5861
{
5962
using accessor_t = Accessor;
60-
using value_t = typename accessor_t::value_t;
63+
using angle_t = typename accessor_t::angle_t;
64+
using candela_t = typename accessor_t::candela_t;
6165
using symmetry_t = ProfileProperties::LuminairePlanesSymmetry;
62-
using polar_t = math::Polar<float32_t>;
63-
using octahedral_t = math::OctahedralTransform<float32_t>;
66+
using polar_t = math::Polar<float32_t>;
67+
using octahedral_t = math::OctahedralTransform<float32_t>;
68+
using vector2_type = float32_t2;
69+
70+
vector2_type halfMinusHalfPixel;
6471

65-
static value_t sample(NBL_CONST_REF_ARG(accessor_t) accessor, NBL_CONST_REF_ARG(math::Polar<float32_t>) polar)
72+
static inline CandelaSampler create(NBL_CONST_REF_ARG(vector2_type) lastTexelRcp)
6673
{
67-
// TODO: DXC seems to have a bug and cannot use symmetry_t directly with == operator https://godbolt.devsh.eu/z/P9Kc5x
68-
const ProfileProperties::LuminairePlanesSymmetry symmetry = accessor.getProperties().getSymmetry();
69-
const float32_t vAngle = degrees(polar.theta);
70-
const float32_t hAngle = degrees(wrapPhi(polar.phi, symmetry));
74+
CandelaSampler retval;
75+
retval.halfMinusHalfPixel = vector2_type(0.5f, 0.5f) / (vector2_type(1.f, 1.f) + lastTexelRcp);
76+
return retval;
77+
}
7178

72-
const float32_t vABack = accessor.vAngle(accessor.vAnglesCount() - 1u);
73-
if (vAngle > vABack)
74-
return 0.f;
79+
inline candela_t operator()(NBL_CONST_REF_ARG(accessor_t) accessor, NBL_CONST_REF_ARG(polar_t) polar) NBL_CONST_MEMBER_FUNC
80+
{
81+
assert(polar.theta >= float32_t(0.0) && polar.theta <= numbers::pi<float32_t>);
82+
assert(hlsl::abs(polar.phi) <= numbers::pi<float32_t> * float32_t(2.0));
7583

76-
const uint32_t j0 = getVLB(accessor, vAngle);
77-
const uint32_t j1 = getVUB(accessor, vAngle);
78-
const uint32_t i0 = (symmetry == ProfileProperties::LuminairePlanesSymmetry::ISOTROPIC) ? 0u : getHLB(accessor, hAngle);
79-
const uint32_t i1 = (symmetry == ProfileProperties::LuminairePlanesSymmetry::ISOTROPIC) ? 0u : getHUB(accessor, hAngle);
84+
const symmetry_t symmetry = accessor.getProperties().getSymmetry();
85+
const angle_t vAngle = degrees(polar.theta);
86+
const angle_t hAngle = degrees(__wrapPhi(polar.phi, symmetry));
8087

81-
const float32_t uReciprocal = ((i1 == i0) ? 1.f : 1.f / (accessor.hAngle(i1) - accessor.hAngle(i0)));
82-
const float32_t vReciprocal = ((j1 == j0) ? 1.f : 1.f / (accessor.vAngle(j1) - accessor.vAngle(j0)));
88+
#define NBL_IES_DEF_ANGLE_ACC(T, EXPR) struct T { using value_type = angle_t; accessor_t acc; value_type operator[](uint32_t idx) NBL_CONST_MEMBER_FUNC { return EXPR; } };
8389

84-
const float32_t u = ((hAngle - accessor.hAngle(i0)) * uReciprocal);
85-
const float32_t v = ((vAngle - accessor.vAngle(j0)) * vReciprocal);
90+
NBL_IES_DEF_ANGLE_ACC(VAcc, acc.vAngle(idx))
91+
NBL_IES_DEF_ANGLE_ACC(HAcc, acc.hAngle(idx))
8692

87-
const float32_t s0 = (accessor.value(uint32_t2(i0, j0)) * (1.f - v) + accessor.value(uint32_t2(i0, j1)) * v);
88-
const float32_t s1 = (accessor.value(uint32_t2(i1, j0)) * (1.f - v) + accessor.value(uint32_t2(i1, j1)) * v);
93+
VAcc vAcc; vAcc.acc = accessor; HAcc hAcc; hAcc.acc = accessor;
8994

90-
return s0 * (1.f - u) + s1 * u;
91-
}
95+
#undef NBL_IES_DEF_ANGLE_ACC
9296

93-
static value_t sample(NBL_CONST_REF_ARG(accessor_t) accessor, NBL_CONST_REF_ARG(float32_t2) uv)
94-
{
95-
const float32_t3 dir = octahedral_t::uvToDir(uv);
96-
const polar_t polar = polar_t::createFromCartesian(dir);
97-
return sample(accessor, polar);
98-
}
97+
const uint32_t vCount = accessor.vAnglesCount();
98+
const uint32_t hCount = accessor.hAnglesCount();
99+
const angle_t vABack = vAcc[vCount - 1u];
100+
if (vAngle > vABack)
101+
return candela_t(0);
99102

100-
static float32_t wrapPhi(const float32_t phi, const symmetry_t symmetry)
101-
{
102-
switch (symmetry)
103-
{
104-
case symmetry_t::ISOTROPIC: //! axial symmetry
105-
return 0.0f;
106-
case symmetry_t::QUAD_SYMETRIC: //! phi MIRROR_REPEAT wrap onto [0, 90] degrees range
107-
{
108-
NBL_CONSTEXPR float32_t M_HALF_PI = numbers::pi<float32_t> * 0.5f;
109-
float32_t wrapPhi = abs(phi); //! first MIRROR
110-
if (wrapPhi > M_HALF_PI) //! then REPEAT
111-
wrapPhi = hlsl::clamp(M_HALF_PI - (wrapPhi - M_HALF_PI), 0.f, M_HALF_PI);
112-
return wrapPhi; //! eg. maps (in degrees) 91,269,271 -> 89 and 179,181,359 -> 1
113-
}
114-
case symmetry_t::HALF_SYMETRIC: //! phi MIRROR wrap onto [0, 180] degrees range
115-
case symmetry_t::OTHER_HALF_SYMMETRIC: //! eg. maps (in degress) 181 -> 179 or 359 -> 1
116-
return abs(phi);
117-
case symmetry_t::NO_LATERAL_SYMMET: //! plot onto whole (in degress) [0, 360] range
118-
{
119-
NBL_CONSTEXPR float32_t M_TWICE_PI = numbers::pi<float32_t> *2.f;
120-
return (phi < 0.f) ? (phi + M_TWICE_PI) : phi;
121-
}
122-
}
123-
return 69.f;
124-
}
103+
const uint32_t vUbRaw = __upperBound(vAcc, vCount, vAngle);
104+
const uint32_t vLb = __lowerFromUpper(vUbRaw);
105+
const uint32_t vUb = __clampUpper(vUbRaw, vCount);
125106

126-
struct impl_t
127-
{
128-
static uint32_t getVUB(NBL_CONST_REF_ARG(accessor_t) accessor, const float32_t angle)
129-
{
130-
for (uint32_t i = 0u; i < accessor.vAnglesCount(); ++i)
131-
if (accessor.vAngle(i) > angle)
132-
return i;
133-
return accessor.vAnglesCount();
134-
}
107+
const bool isotropic = (symmetry == symmetry_t::ISOTROPIC);
108+
const uint32_t hUbRaw = isotropic ? 0u : __upperBound(hAcc, hCount, hAngle);
109+
const uint32_t hLb = isotropic ? 0u : __lowerFromUpper(hUbRaw);
110+
const uint32_t hUb = isotropic ? 0u : __clampUpper(hUbRaw, hCount);
135111

136-
static uint32_t getHUB(NBL_CONST_REF_ARG(accessor_t) accessor, const float32_t angle)
137-
{
138-
for (uint32_t i = 0u; i < accessor.hAnglesCount(); ++i)
139-
if (accessor.hAngle(i) > angle)
140-
return i;
141-
return accessor.hAnglesCount();
142-
}
143-
};
112+
const angle_t uReciprocal = (hUb == hLb) ? angle_t(1) : angle_t(1) / (hAcc[hUb] - hAcc[hLb]);
113+
const angle_t vReciprocal = (vUb == vLb) ? angle_t(1) : angle_t(1) / (vAcc[vUb] - vAcc[vLb]);
144114

145-
static uint32_t getVLB(NBL_CONST_REF_ARG(accessor_t) accessor, const float32_t angle)
146-
{
147-
return (uint32_t)hlsl::max((int64_t)impl_t::getVUB(accessor, angle) - 1ll, 0ll);
148-
}
115+
const angle_t u = (hAngle - hAcc[hLb]) * uReciprocal;
116+
const angle_t v = (vAngle - vAcc[vLb]) * vReciprocal;
149117

150-
static uint32_t getHLB(NBL_CONST_REF_ARG(accessor_t) accessor, const float32_t angle)
151-
{
152-
return (uint32_t)hlsl::max((int64_t)impl_t::getHUB(accessor, angle) - 1ll, 0ll);
118+
const candela_t s0 = accessor.value(uint32_t2(hLb, vLb)) * (angle_t(1) - v) + accessor.value(uint32_t2(hLb, vUb)) * v;
119+
const candela_t s1 = accessor.value(uint32_t2(hUb, vLb)) * (angle_t(1) - v) + accessor.value(uint32_t2(hUb, vUb)) * v;
120+
121+
return s0 * (angle_t(1) - u) + s1 * u;
153122
}
154123

155-
static uint32_t getVUB(NBL_CONST_REF_ARG(accessor_t) accessor, const float32_t angle)
124+
inline candela_t operator()(NBL_CONST_REF_ARG(accessor_t) accessor, NBL_CONST_REF_ARG(float32_t2) uv) NBL_CONST_MEMBER_FUNC
156125
{
157-
return (uint32_t)hlsl::min((int64_t)impl_t::getVUB(accessor, angle), (int64_t)(accessor.vAnglesCount() - 1u));
126+
const float32_t3 dir = octahedral_t::uvToDir(uv, halfMinusHalfPixel);
127+
const polar_t polar = polar_t::createFromCartesian(dir);
128+
return operator()(accessor, polar);
158129
}
159130

160-
static uint32_t getHUB(NBL_CONST_REF_ARG(accessor_t) accessor, const float32_t angle)
131+
template<typename View>
132+
static inline uint32_t __upperBound(NBL_REF_ARG(View) view, const uint32_t count, const angle_t angle) { return nbl::hlsl::upper_bound(view, 0u, count, angle); }
133+
134+
static inline uint32_t __lowerFromUpper(const uint32_t ubRaw) { return ubRaw > 0u ? (ubRaw - 1u) : 0u; }
135+
136+
static inline uint32_t __clampUpper(const uint32_t ubRaw, const uint32_t count) { return ubRaw < count ? ubRaw : (count - 1u); }
137+
138+
static inline angle_t __wrapPhi(const angle_t phi, const symmetry_t symmetry)
161139
{
162-
return (uint32_t)hlsl::min((int64_t)impl_t::getHUB(accessor, angle), (int64_t)(accessor.hAnglesCount() - 1u));
140+
switch (symmetry)
141+
{
142+
case symmetry_t::ISOTROPIC: //! axial symmetry
143+
return angle_t(0.0);
144+
case symmetry_t::QUAD_SYMETRIC: //! phi MIRROR_REPEAT wrap onto [0, 90] degrees range
145+
{
146+
const angle_t HalfPI = numbers::pi<angle_t> * angle_t(0.5);
147+
angle_t wrapPhi = hlsl::abs(phi); //! first MIRROR
148+
if (wrapPhi > HalfPI) //! then REPEAT
149+
wrapPhi = hlsl::clamp(HalfPI - (wrapPhi - HalfPI), angle_t(0), HalfPI);
150+
return wrapPhi; //! eg. maps (in degrees) 91,269,271 -> 89 and 179,181,359 -> 1
151+
}
152+
case symmetry_t::HALF_SYMETRIC: //! phi MIRROR wrap onto [0, 180] degrees range
153+
case symmetry_t::OTHER_HALF_SYMMETRIC: //! eg. maps (in degress) 181 -> 179 or 359 -> 1
154+
return hlsl::abs(phi);
155+
case symmetry_t::NO_LATERAL_SYMMET: //! plot onto whole (in degress) [0, 360] range
156+
{
157+
const angle_t TwicePI = numbers::pi<angle_t> * angle_t(2.0);
158+
return (phi < angle_t(0)) ? (phi + TwicePI) : phi;
159+
}
160+
}
161+
162+
return bit_cast<angle_t>(numeric_limits<float32_t>::quiet_NaN);
163163
}
164164
};
165165

0 commit comments

Comments
 (0)