|
7 | 7 | namespace facade::editor { |
8 | 8 | namespace { |
9 | 9 | bool eq(float const a, float const b, float const epsilon = 0.001f) { return std::abs(a - b) < epsilon; } |
10 | | -constexpr glm::vec3 to_radian(glm::vec3 const& angles) { return {glm::radians(angles.x), glm::radians(angles.y), glm::radians(angles.z)}; } |
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 { |
@@ -54,25 +53,31 @@ bool Inspector::inspect(char const* label, glm::vec4& out_vec4, float speed, flo |
54 | 53 |
|
55 | 54 | bool Inspector::inspect(char const* label, glm::quat& out_quat) const { |
56 | 55 | auto euler = to_degree(glm::eulerAngles(out_quat)); |
| 56 | + auto const org = euler; |
57 | 57 | if (inspect(label, euler, 0.5f, -180.0f, 180.0f)) { |
58 | | - static constexpr auto y_limit_v{90.0f}; |
59 | | - if (euler.y < -y_limit_v) { euler.y = y_limit_v; } |
60 | | - if (euler.y > y_limit_v) { euler.y = -y_limit_v; } |
61 | | - out_quat = glm::quat(to_radian(euler)); |
| 58 | + if (auto const diff = org.x - euler.x; std::abs(diff) > 0.0f) { out_quat = glm::rotate(out_quat, glm::radians(diff), right_v); } |
| 59 | + if (auto const diff = org.y - euler.y; std::abs(diff) > 0.0f) { out_quat = glm::rotate(out_quat, glm::radians(diff), up_v); } |
| 60 | + if (auto const diff = org.z - euler.z; std::abs(diff) > 0.0f) { out_quat = glm::rotate(out_quat, glm::radians(diff), front_v); } |
62 | 61 | return true; |
63 | 62 | } |
64 | 63 | return false; |
65 | 64 | } |
66 | 65 |
|
67 | | -bool Inspector::inspect(Transform& out_transform) const { |
| 66 | +bool Inspector::inspect(Transform& out_transform, Bool& out_unified_scaling) const { |
68 | 67 | auto ret = Modified{}; |
69 | 68 | if (ImGui::CollapsingHeader("Transform", ImGuiTreeNodeFlags_DefaultOpen)) { |
70 | 69 | auto vec3 = out_transform.position(); |
71 | 70 | if (ret(inspect("Position", vec3))) { out_transform.set_position(vec3); } |
72 | 71 | auto quat = out_transform.orientation(); |
73 | 72 | if (ret(inspect("Orientation", quat))) { out_transform.set_orientation(quat); } |
74 | 73 | vec3 = out_transform.scale(); |
75 | | - if (ret(inspect("Scale", vec3))) { out_transform.set_scale(vec3); } |
| 74 | + if (out_unified_scaling) { |
| 75 | + if (ret(ImGui::DragFloat("Scale", &vec3.x, 0.1f))) { out_transform.set_scale({vec3.x, vec3.x, vec3.x}); } |
| 76 | + } else { |
| 77 | + if (ret(inspect("Scale", vec3, 0.1f))) { out_transform.set_scale(vec3); } |
| 78 | + } |
| 79 | + ImGui::SameLine(); |
| 80 | + ImGui::Checkbox("Unified", &out_unified_scaling.value); |
76 | 81 | } |
77 | 82 | return ret.value; |
78 | 83 | } |
@@ -107,11 +112,11 @@ bool SceneInspector::inspect(Id<Material> material_id) const { |
107 | 112 | return false; |
108 | 113 | } |
109 | 114 |
|
110 | | -bool SceneInspector::inspect(Id<Node> node_id) const { |
| 115 | +bool SceneInspector::inspect(Id<Node> node_id, Bool& out_unified_scaling) const { |
111 | 116 | auto ret = Modified{}; |
112 | 117 | auto* node = m_scene.find(node_id); |
113 | 118 | if (!node) { return false; } |
114 | | - ret(inspect(node->transform)); |
| 119 | + ret(inspect(node->transform, out_unified_scaling)); |
115 | 120 | if (auto const* mesh_id = node->find<Id<Mesh>>()) { ret(inspect(*mesh_id)); } |
116 | 121 | return ret.value; |
117 | 122 | } |
|
0 commit comments