7
7
8
8
namespace facade ::editor {
9
9
namespace {
10
- bool eq (float const a, float const b, float const epsilon = 0 .001f ) { return std::abs (a - b) < epsilon; }
11
10
constexpr glm::vec3 to_degree (glm::vec3 const & angles) { return {glm::degrees (angles.x ), glm::degrees (angles.y ), glm::degrees (angles.z )}; }
12
11
13
12
struct Modified {
@@ -18,36 +17,41 @@ struct Modified {
18
17
return modified;
19
18
}
20
19
};
21
- } // namespace
22
20
23
- bool Inspector::inspect (char const * label, glm::vec2& out_vec2, float speed, float lo, float hi) const {
24
- float arr[2 ] = {out_vec2.x , out_vec2.y };
25
- ImGui::DragFloat2 (label, arr, speed, lo, hi);
26
- if (!eq (arr[0 ], out_vec2.x ) || !eq (arr[1 ], out_vec2.y )) {
27
- out_vec2 = {arr[0 ], arr[1 ]};
21
+ using DragFloatFunc = bool (*)(const char *, float * v, float , float , float , const char *, ImGuiSliderFlags);
22
+
23
+ constexpr DragFloatFunc drag_float_vtable[] = {
24
+ nullptr , &ImGui::DragFloat, &ImGui::DragFloat2, &ImGui::DragFloat3, &ImGui::DragFloat4,
25
+ };
26
+
27
+ template <std::size_t Dim>
28
+ bool drag_float (char const * label, float (&data)[Dim], float speed, float lo, float hi, int flags = {}) {
29
+ static_assert (Dim > 0 && Dim < std::size (drag_float_vtable));
30
+ return drag_float_vtable[Dim](label, data, speed, lo, hi, " %.3f" , flags);
31
+ }
32
+
33
+ template <std::size_t Dim>
34
+ bool inspect_vec (char const * label, glm::vec<static_cast <int >(Dim), float>& out_vec, float speed, float lo, float hi) {
35
+ float data[Dim]{};
36
+ std::memcpy (data, &out_vec, Dim * sizeof (float ));
37
+ if (drag_float (label, data, speed, lo, hi)) {
38
+ std::memcpy (&out_vec, data, Dim * sizeof (float ));
28
39
return true ;
29
40
}
30
41
return false ;
31
42
}
43
+ } // namespace
44
+
45
+ bool Inspector::inspect (char const * label, glm::vec2& out_vec2, float speed, float lo, float hi) const {
46
+ return inspect_vec<2 >(label, out_vec2, speed, lo, hi);
47
+ }
32
48
33
49
bool Inspector::inspect (char const * label, glm::vec3& out_vec3, float speed, float lo, float hi) const {
34
- float arr[3 ] = {out_vec3.x , out_vec3.y , out_vec3.z };
35
- ImGui::DragFloat3 (label, arr, speed, lo, hi);
36
- if (!eq (arr[0 ], out_vec3.x ) || !eq (arr[1 ], out_vec3.y ) || !eq (arr[2 ], out_vec3.z )) {
37
- out_vec3 = {arr[0 ], arr[1 ], arr[2 ]};
38
- return true ;
39
- }
40
- return false ;
50
+ return inspect_vec<3 >(label, out_vec3, speed, lo, hi);
41
51
}
42
52
43
53
bool Inspector::inspect (char const * label, glm::vec4& out_vec4, float speed, float lo, float hi) const {
44
- float arr[4 ] = {out_vec4.x , out_vec4.y , out_vec4.z , out_vec4.w };
45
- ImGui::DragFloat4 (label, arr, speed, lo, hi);
46
- if (!eq (arr[0 ], out_vec4.x ) || !eq (arr[1 ], out_vec4.y ) || !eq (arr[2 ], out_vec4.z ) || !eq (arr[3 ], out_vec4.w )) {
47
- out_vec4 = {arr[0 ], arr[1 ], arr[2 ], arr[3 ]};
48
- return true ;
49
- }
50
- return false ;
54
+ return inspect_vec<4 >(label, out_vec4, speed, lo, hi);
51
55
}
52
56
53
57
bool Inspector::inspect (char const * label, nvec3& out_vec3, float speed) const {
@@ -61,8 +65,10 @@ bool Inspector::inspect(char const* label, nvec3& out_vec3, float speed) const {
61
65
62
66
bool Inspector::inspect (char const * label, glm::quat& out_quat) const {
63
67
auto euler = to_degree (glm::eulerAngles (out_quat));
68
+ float deg[3 ] = {euler.x , euler.y , euler.z };
64
69
auto const org = euler;
65
- if (inspect (label, euler, 0 .5f , -180 .0f , 180 .0f )) {
70
+ if (drag_float (label, deg, 0 .5f , -180 .0f , 180 .0f , ImGuiSliderFlags_NoInput)) {
71
+ euler = {deg[0 ], deg[1 ], deg[2 ]};
66
72
if (auto const diff = org.x - euler.x ; std::abs (diff) > 0 .0f ) { out_quat = glm::rotate (out_quat, glm::radians (diff), right_v); }
67
73
if (auto const diff = org.y - euler.y ; std::abs (diff) > 0 .0f ) { out_quat = glm::rotate (out_quat, glm::radians (diff), up_v); }
68
74
if (auto const diff = org.z - euler.z ; std::abs (diff) > 0 .0f ) { out_quat = glm::rotate (out_quat, glm::radians (diff), front_v); }
0 commit comments