Skip to content

Commit 502c80c

Browse files
authored
overhaul transform gizmo, add ImGizmo, allow user-created gizmos (#375)
* overhaul transform gizmo, add ImGizmo, allow user-created gizmos * second attempt at adding submodule * more utility functions * add error for get if not present * add position setter/getter
1 parent b38da6d commit 502c80c

File tree

18 files changed

+400
-621
lines changed

18 files changed

+400
-621
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,6 @@
1515
[submodule "deps/imgui/implot"]
1616
path = deps/imgui/implot
1717
url = https://github.com/epezent/implot
18+
[submodule "deps/imgui/ImGuizmo"]
19+
path = deps/imgui/ImGuizmo
20+
url = https://github.com/CedricGuillemet/ImGuizmo.git

deps/imgui/CMakeLists.txt

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,26 @@ endif()
2020
if("${POLYSCOPE_BACKEND_OPENGL3_GLFW}")
2121

2222
# imgui sources
23-
list(APPEND SRCS imgui/imgui.cpp imgui/imgui_draw.cpp imgui/imgui_tables.cpp imgui/imgui_widgets.cpp imgui/imgui_demo.cpp imgui/backends/imgui_impl_glfw.cpp imgui/backends/imgui_impl_opengl3.cpp)
23+
list(APPEND SRCS
24+
imgui/imgui.cpp
25+
imgui/imgui_draw.cpp
26+
imgui/imgui_tables.cpp
27+
imgui/imgui_widgets.cpp
28+
imgui/imgui_demo.cpp
29+
imgui/backends/imgui_impl_glfw.cpp
30+
imgui/backends/imgui_impl_opengl3.cpp
31+
)
2432

2533
# implot sources
2634
list(APPEND SRCS
2735
implot/implot.cpp
2836
implot/implot_items.cpp
2937
)
38+
39+
# imguizmosources
40+
list(APPEND SRCS
41+
ImGuizmo/ImGuizmo.cpp
42+
)
3043

3144
add_library(
3245
imgui
@@ -35,7 +48,7 @@ if("${POLYSCOPE_BACKEND_OPENGL3_GLFW}")
3548

3649
target_include_directories(imgui PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/imgui/")
3750
target_include_directories(imgui PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/implot/")
38-
target_include_directories(imgui PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../glfw/include/")
51+
target_include_directories(imgui PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/ImGuizmo/")
3952
target_include_directories(imgui PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../glad/include/")
4053

4154
target_link_libraries(imgui PRIVATE glfw)

deps/imgui/ImGuizmo

Submodule ImGuizmo added at df1c301

include/polyscope/color_bar.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ class OnscreenColorBarWidget : public Widget {
8181
public:
8282
OnscreenColorBarWidget(ColorBar& parent_);
8383
virtual void draw() override;
84+
std::string uniquePrefix() override;
8485

8586
private:
8687
ColorBar& parent;

include/polyscope/context.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class Structure;
2828
class Group;
2929
class SlicePlane;
3030
class Widget;
31+
class TransformationGizmo;
3132
class FloatingQuantityStructure;
3233
namespace view {
3334
extern const double defaultNearClipRatio;
@@ -115,6 +116,16 @@ struct Context {
115116

116117
bool pointCloudEfficiencyWarningReported = false;
117118
FloatingQuantityStructure* globalFloatingQuantityStructure = nullptr;
119+
120+
// ======================================================
121+
// === Other various global lists
122+
// ======================================================
123+
124+
// Transformation gizmos that were created by hte user for the secne
125+
// Note: this does _not_ include all gizmos, such as the one which exists
126+
// for each structure. This is just storage for gizmos explicitly created
127+
// like with addTransformationGizmo()
128+
std::vector<std::unique_ptr<TransformationGizmo>> createdTransformationGizmos;
118129
};
119130

120131

include/polyscope/structure.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ class Structure : public render::ManagedBufferRegistry, public virtual WeakRefer
8484
void translate(glm::vec3 vec); // *adds* vec to the position
8585
glm::mat4x4 getTransform();
8686
glm::vec3 getPosition();
87+
TransformationGizmo& getTransformGizmo();
8788

8889
void setStructureUniforms(render::ShaderProgram& p);
8990
bool wantsCullPosition();

include/polyscope/transformation_gizmo.h

Lines changed: 81 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include "polyscope/utilities.h"
88
#include "polyscope/widget.h"
99

10+
#include "ImGuizmo.h"
11+
1012
namespace polyscope {
1113

1214
// A visual widget with handles for translations/rotations
@@ -16,76 +18,108 @@ class TransformationGizmo : public Widget {
1618
public:
1719
// == Constructors
1820

19-
TransformationGizmo(std::string name, glm::mat4& T, PersistentValue<glm::mat4>* Tpers = nullptr);
21+
// Construct a gizmo.
22+
//
23+
// If T is null, this gizmo owns its transform matrix which can be accessed via set/getTransform().
24+
// If T is non-null, the gizmo will manipulate that external transform. Optionally, a pointer can also be passed to a
25+
// PersistentValue<glm::mat4>, which will be updated as the transform is changed.
26+
//
27+
// Users creating additional gizmos should not call this, use addTransformationGizmo() instead.
28+
TransformationGizmo(std::string name, glm::mat4* T = nullptr, PersistentValue<glm::mat4>* Tpers = nullptr);
2029

2130

2231
// == Key members
2332

2433
// a unique name
2534
const std::string name;
2635

27-
// the main transform encoded by the gizmo
28-
PersistentValue<bool> enabled;
36+
// NOTE: this is only meaningful to call on use-created gizmos from addTransformationGizmo(),
37+
// it will have no effect on gizmos created other ways
38+
// After removing, the object is destructed
39+
void remove();
2940

30-
// the main transform encoded by the gizmo
31-
// note that this is a reference set on construction; the gizmo wraps a transform defined somewhere else
32-
glm::mat4& T;
33-
PersistentValue<glm::mat4>* Tpers; // optional, a persistent value defined elsewhere that goes with T
41+
// == Getters and setters
3442

35-
// == Member functions
43+
glm::mat4 getTransform();
44+
void setTransform(glm::mat4 newT);
3645

37-
void prepare();
38-
void draw() override;
39-
bool interact() override;
46+
// the are helpers which access/update only the position component of the transform
47+
glm::vec3 getPosition();
48+
void setPosition(glm::vec3 newPos);
4049

41-
protected:
42-
enum class TransformHandle { None, Rotation, Translation, Scale };
50+
bool getEnabled();
51+
void setEnabled(bool newVal);
4352

53+
bool getAllowTranslation();
54+
void setAllowTranslation(bool newVal);
4455

45-
// parameters
46-
const float gizmoSizeRel = 0.08;
47-
const float diskWidthObj = 0.1; // in object coordinates, before transformation
48-
const float vecLength = 1.5;
49-
const float sphereRad = 0.32;
50-
const std::string material = "wax";
56+
bool getAllowRotation();
57+
void setAllowRotation(bool newVal);
5158

52-
// state
53-
int selectedDim = -1; // must be {0,1,2} if selectedType == Rotation/Translation
54-
TransformHandle selectedType = TransformHandle::None;
55-
bool currentlyDragging = false;
56-
glm::vec3 dragPrevVec{1., 0.,
57-
0.}; // the normal vector from the previous frame of the drag OR previous translation center
59+
bool getAllowScaling();
60+
void setAllowScaling(bool newVal);
5861

59-
std::array<glm::vec3, 3> niceRGB = {{glm::vec3{211 / 255., 45 / 255., 62 / 255.},
60-
glm::vec3{65 / 255., 121 / 255., 225 / 255.},
61-
glm::vec3{95 / 255., 175 / 255., 35 / 255.}}};
62+
// sadly this is not really supported by ImGuizmo
63+
// bool getUniformScaling();
64+
// void setUniformScaling(bool newVal);
6265

63-
void markUpdated();
66+
bool getInteractInLocalSpace();
67+
void setInteractInLocalSpace(bool newVal);
6468

65-
// Render stuff
66-
std::shared_ptr<render::ShaderProgram> ringProgram;
67-
std::shared_ptr<render::ShaderProgram> arrowProgram;
68-
std::shared_ptr<render::ShaderProgram> sphereProgram;
69+
// Size is relative, with 1.0 as the default size
70+
float getGizmoSize();
71+
void setGizmoSize(float newVal);
6972

70-
// Geometry helpers used to test hits
73+
// == Member functions
7174

72-
// returns <tRay, distNearest, nearestPoint>
73-
std::tuple<float, float, glm::vec3> circleTest(glm::vec3 raySource, glm::vec3 rayDir, glm::vec3 center,
74-
glm::vec3 normal, float radius);
75-
std::tuple<float, float, glm::vec3> lineTest(glm::vec3 raySource, glm::vec3 rayDir, glm::vec3 center,
76-
glm::vec3 tangent, float length);
77-
std::tuple<float, float, glm::vec3> sphereTest(glm::vec3 raySource, glm::vec3 rayDir, glm::vec3 center, float radius,
78-
bool allowHitSurface = true);
75+
std::string uniquePrefix() override;
76+
void draw() override;
77+
bool interact() override;
78+
void buildUI() override;
79+
void buildInlineTransformUI();
80+
void buildMenuItems();
81+
void markUpdated();
7982

83+
protected:
84+
// The main transform encoded by the gizmo
85+
// This can be either a reference to an external wrapped transform, or the internal storage below
86+
glm::mat4& Tref;
8087

81-
std::tuple<std::vector<glm::vec3>, std::vector<glm::vec3>, std::vector<glm::vec3>, std::vector<glm::vec2>,
82-
std::vector<glm::vec3>>
83-
triplePlaneCoords();
88+
// Optional, a persistent value defined elsewhere that goes with T, which
89+
// will be marked as updated when the gizmo changes the transform.
90+
PersistentValue<glm::mat4>* Tpers;
8491

85-
std::tuple<std::vector<glm::vec3>, std::vector<glm::vec3>, std::vector<glm::vec3>, std::vector<glm::vec3>>
86-
tripleArrowCoords();
92+
// Local stoarage for a transformation.
93+
// This may or may not be used; based on the constructor args this class may wrap an external transform, or simply use
94+
// this one.
95+
glm::mat4 Towned = glm::mat4(1.0);
8796

88-
// std::tuple<std::vector<glm::vec3>, std::vector<glm::vec3>> unitCubeCoords();
97+
// options
98+
PersistentValue<bool> enabled;
99+
PersistentValue<bool> allowTranslation;
100+
PersistentValue<bool> allowRotation;
101+
PersistentValue<bool> allowScaling;
102+
// PersistentValue<bool> uniformScaling; // not really supported by the ImGuizmo
103+
PersistentValue<bool> interactInLocalSpace;
104+
PersistentValue<bool> showUIWindow;
105+
PersistentValue<float> gizmoSize;
106+
107+
// internal
108+
bool lastInteractResult = false;
89109
};
90110

111+
// Create a user-defined transformation gizmo in the scene.
112+
// By default, the gizmo maintains its own transformation matrix which
113+
// can be accessed by by .getTransform(). Optionally, it can instead wrap
114+
// and existin transform passed as transformToWrap.
115+
TransformationGizmo* addTransformationGizmo(std::string name = "", glm::mat4* transformToWrap = nullptr);
116+
117+
// Get a user-created transformation gizmo by name
118+
TransformationGizmo* getTransformationGizmo(std::string name);
119+
120+
// Remove a user-created transformation gizmo
121+
void removeTransformationGizmo(TransformationGizmo* gizmo);
122+
void removeTransformationGizmo(std::string name);
123+
void removeAllTransformationGizmos();
124+
91125
} // namespace polyscope

include/polyscope/widget.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ class Widget : public virtual WeakReferrable {
2020

2121
virtual void draw();
2222
virtual bool interact(); // returns true if the mouse input was consumed
23-
virtual void buildGUI();
23+
virtual void buildUI();
24+
virtual std::string uniquePrefix() = 0;
2425

2526
}; // namespace polyscope
2627
} // namespace polyscope

src/color_bar.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,10 @@ void ColorBar::prepareOnscreenColorBar() {
205205

206206
OnscreenColorBarWidget::OnscreenColorBarWidget(ColorBar& parent_) : parent(parent_) {}
207207

208+
std::string OnscreenColorBarWidget::uniquePrefix() {
209+
return "#widget#OnscreenColorBarWidget#" + parent.parent.uniquePrefix();
210+
}
211+
208212
void OnscreenColorBarWidget::draw() {
209213
if (!parent.parent.isEnabled()) return;
210214
if (!parent.getOnscreenColorbarEnabled()) return;

src/polyscope.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1032,7 +1032,7 @@ void draw(bool withUI, bool withContextCallback) {
10321032
for (WeakHandle<Widget> wHandle : state::widgets) {
10331033
if (wHandle.isValid()) {
10341034
Widget& w = wHandle.get();
1035-
w.buildGUI();
1035+
w.buildUI();
10361036
}
10371037
}
10381038
}
@@ -1171,6 +1171,7 @@ void shutdown(bool allowMidFrameShutdown) {
11711171
removeAllStructures();
11721172
removeAllGroups();
11731173
removeAllSlicePlanes();
1174+
removeAllTransformationGizmos();
11741175
clearMessages();
11751176
state::userCallback = nullptr;
11761177
state::filesDroppedCallback = nullptr;

0 commit comments

Comments
 (0)