KarmaEngine
Game Engine for practical learning and research purposes
Loading...
Searching...
No Matches
KarmaGuizmo.h
1// https://github.com/CedricGuillemet/KarmaGuizmo
2// v1.92.5 WIP
3//
4// The MIT License(MIT)
5//
6// Copyright(c) 2016-2021 Cedric Guillemet
7//
8// Permission is hereby granted, free of charge, to any person obtaining a copy
9// of this software and associated documentation files(the "Software"), to deal
10// in the Software without restriction, including without limitation the rights
11// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
12// copies of the Software, and to permit persons to whom the Software is
13// furnished to do so, subject to the following conditions :
14//
15// The above copyright notice and this permission notice shall be included in all
16// copies or substantial portions of the Software.
17//
18// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
21// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24// SOFTWARE.
25//
26// -------------------------------------------------------------------------------------------
27// History :
28// 2019/11/03 View gizmo
29// 2016/09/11 Behind camera culling. Scaling Delta matrix not multiplied by source matrix scales. local/world rotation and translation fixed. Display message is incorrect (X: ... Y:...) in local mode.
30// 2016/09/09 Hatched negative axis. Snapping. Documentation update.
31// 2016/09/04 Axis switch and translation plan autohiding. Scale transform stability improved
32// 2016/09/01 Mogwai changed to Manipulate. Draw debug cube. Fixed inverted scale. Mixing scale and translation/rotation gives bad results.
33// 2016/08/31 First version
34//
35// -------------------------------------------------------------------------------------------
36// Future (no order):
37//
38// - Multi view
39// - display rotation/translation/scale infos in local/world space and not only local
40// - finish local/world matrix application
41// - OPERATION as bitmask
42//
43// -------------------------------------------------------------------------------------------
44// Example
45#if 0
46void EditTransform(const Camera& camera, matrix_t& matrix)
47{
48 static KarmaGuizmo::OPERATION mCurrentGizmoOperation(KarmaGuizmo::ROTATE);
49 static KarmaGuizmo::MODE mCurrentGizmoMode(KarmaGuizmo::WORLD);
50 if (KarmaGui::IsKeyPressed(90))
51 mCurrentGizmoOperation = KarmaGuizmo::TRANSLATE;
52 if (KarmaGui::IsKeyPressed(69))
53 mCurrentGizmoOperation = KarmaGuizmo::ROTATE;
54 if (KarmaGui::IsKeyPressed(82)) // r Key
55 mCurrentGizmoOperation = KarmaGuizmo::SCALE;
56 if (KarmaGui::RadioButton("Translate", mCurrentGizmoOperation == KarmaGuizmo::TRANSLATE))
57 mCurrentGizmoOperation = KarmaGuizmo::TRANSLATE;
58 KarmaGui::SameLine();
59 if (KarmaGui::RadioButton("Rotate", mCurrentGizmoOperation == KarmaGuizmo::ROTATE))
60 mCurrentGizmoOperation = KarmaGuizmo::ROTATE;
61 KarmaGui::SameLine();
62 if (KarmaGui::RadioButton("Scale", mCurrentGizmoOperation == KarmaGuizmo::SCALE))
63 mCurrentGizmoOperation = KarmaGuizmo::SCALE;
64 float matrixTranslation[3], matrixRotation[3], matrixScale[3];
65 KarmaGuizmo::DecomposeMatrixToComponents(matrix.m16, matrixTranslation, matrixRotation, matrixScale);
66 KarmaGui::InputFloat3("Tr", matrixTranslation, 3);
67 KarmaGui::InputFloat3("Rt", matrixRotation, 3);
68 KarmaGui::InputFloat3("Sc", matrixScale, 3);
69 KarmaGuizmo::RecomposeMatrixFromComponents(matrixTranslation, matrixRotation, matrixScale, matrix.m16);
70
71 if (mCurrentGizmoOperation != KarmaGuizmo::SCALE)
72 {
73 if (KarmaGui::RadioButton("Local", mCurrentGizmoMode == KarmaGuizmo::LOCAL))
74 mCurrentGizmoMode = KarmaGuizmo::LOCAL;
75 KarmaGui::SameLine();
76 if (KarmaGui::RadioButton("World", mCurrentGizmoMode == KarmaGuizmo::WORLD))
77 mCurrentGizmoMode = KarmaGuizmo::WORLD;
78 }
79 static bool useSnap(false);
80 if (KarmaGui::IsKeyPressed(83))
81 useSnap = !useSnap;
82 KarmaGui::Checkbox("", &useSnap);
83 KarmaGui::SameLine();
84 vec_t snap;
85 switch (mCurrentGizmoOperation)
86 {
87 case KarmaGuizmo::TRANSLATE:
88 snap = config.mSnapTranslation;
89 KarmaGui::InputFloat3("Snap", &snap.x);
90 break;
91 case KarmaGuizmo::ROTATE:
92 snap = config.mSnapRotation;
93 KarmaGui::InputFloat("Angle Snap", &snap.x);
94 break;
95 case KarmaGuizmo::SCALE:
96 snap = config.mSnapScale;
97 KarmaGui::InputFloat("Scale Snap", &snap.x);
98 break;
99 }
100 KarmaGuiIO& io = Karma::KarmaGui::GetIO();
101 KarmaGuizmo::SetRect(0, 0, io.DisplaySize.x, io.DisplaySize.y);
102 KarmaGuizmo::Manipulate(camera.mView.m16, camera.mProjection.m16, mCurrentGizmoOperation, mCurrentGizmoMode, matrix.m16, NULL, useSnap ? &snap.x : NULL);
103}
104#endif
105#pragma once
106
107#include "KarmaGui.h"
108
109#ifndef KARMAGUI_API
110#define KARMAGUI_API KARMA_API
111#endif
112
113#ifndef KARMAGUIZMO_NAMESPACE
114#define KARMAGUIZMO_NAMESPACE KarmaGuizmo
115#endif
116
117struct KGGuiWindow;
118
119namespace KARMAGUIZMO_NAMESPACE
120{
121 // call inside your own window and before Manipulate() in order to draw gizmo to that window.
122 // Or pass a specific KGDrawList to draw to (e.g. KarmaGui::GetForegroundDrawList()).
123 KARMAGUI_API void SetDrawlist(KGDrawList* drawlist = nullptr);
124
125 // call BeginFrame right after KarmaGui_XXXX_NewFrame();
126 KARMAGUI_API void BeginFrame();
127
128 // this is necessary because when imguizmo is compiled into a dll, and imgui into another
129 // globals are not shared between them.
130 // More details at https://stackoverflow.com/questions/19373061/what-happens-to-global-and-static-variables-in-a-shared-library-when-it-is-dynam
131 // expose method to set imgui context
132 KARMAGUI_API void SetKarmaGuiContext(KarmaGuiContext* ctx);
133
134 // return true if mouse cursor is over any gizmo control (axis, plan or screen component)
135 KARMAGUI_API bool IsOver();
136
137 // return true if mouse IsOver or if the gizmo is in moving state
138 KARMAGUI_API bool IsUsing();
139
140 // return true if the view gizmo is in moving state
141 KARMAGUI_API bool IsUsingViewManipulate();
142 // only check if your mouse is over the view manipulator - no matter whether it's active or not
143 KARMAGUI_API bool IsViewManipulateHovered();
144
145 // return true if any gizmo is in moving state
146 KARMAGUI_API bool IsUsingAny();
147
148 // enable/disable the gizmo. Stay in the state until next call to Enable.
149 // gizmo is rendered with gray half transparent color when disabled
150 KARMAGUI_API void Enable(bool enable);
151
152 // helper functions for manualy editing translation/rotation/scale with an input float
153 // translation, rotation and scale float points to 3 floats each
154 // Angles are in degrees (more suitable for human editing)
155 // example:
156 // float matrixTranslation[3], matrixRotation[3], matrixScale[3];
157 // KarmaGuizmo::DecomposeMatrixToComponents(gizmoMatrix.m16, matrixTranslation, matrixRotation, matrixScale);
158 // KarmaGui::InputFloat3("Tr", matrixTranslation, 3);
159 // KarmaGui::InputFloat3("Rt", matrixRotation, 3);
160 // KarmaGui::InputFloat3("Sc", matrixScale, 3);
161 // KarmaGuizmo::RecomposeMatrixFromComponents(matrixTranslation, matrixRotation, matrixScale, gizmoMatrix.m16);
162 //
163 // These functions have some numerical stability issues for now. Use with caution.
164 KARMAGUI_API void DecomposeMatrixToComponents(const float* matrix, float* translation, float* rotation, float* scale);
165 KARMAGUI_API void RecomposeMatrixFromComponents(const float* translation, const float* rotation, const float* scale, float* matrix);
166
167 KARMAGUI_API void SetRect(float x, float y, float width, float height);
168 // default is false
169 KARMAGUI_API void SetOrthographic(bool isOrthographic);
170
171 // Render a cube with face color corresponding to face normal. Usefull for debug/tests
172 KARMAGUI_API void DrawCubes(const float* view, const float* projection, const float* matrices, int matrixCount);
173 KARMAGUI_API void DrawGrid(const float* view, const float* projection, const float* matrix, const float gridSize);
174
175 // call it when you want a gizmo
176 // Needs view and projection matrices.
177 // matrix parameter is the source matrix (where will be gizmo be drawn) and might be transformed by the function. Return deltaMatrix is optional
178 // translation is applied in world space
179 enum OPERATION
180 {
181 TRANSLATE_X = (1u << 0),
182 TRANSLATE_Y = (1u << 1),
183 TRANSLATE_Z = (1u << 2),
184 ROTATE_X = (1u << 3),
185 ROTATE_Y = (1u << 4),
186 ROTATE_Z = (1u << 5),
187 ROTATE_SCREEN = (1u << 6),
188 SCALE_X = (1u << 7),
189 SCALE_Y = (1u << 8),
190 SCALE_Z = (1u << 9),
191 BOUNDS = (1u << 10),
192 SCALE_XU = (1u << 11),
193 SCALE_YU = (1u << 12),
194 SCALE_ZU = (1u << 13),
195
196 TRANSLATE = TRANSLATE_X | TRANSLATE_Y | TRANSLATE_Z,
197 ROTATE = ROTATE_X | ROTATE_Y | ROTATE_Z | ROTATE_SCREEN,
198 SCALE = SCALE_X | SCALE_Y | SCALE_Z,
199 SCALEU = SCALE_XU | SCALE_YU | SCALE_ZU, // universal
200 UNIVERSAL = TRANSLATE | ROTATE | SCALEU
201 };
202
203 inline OPERATION operator|(OPERATION lhs, OPERATION rhs)
204 {
205 return static_cast<OPERATION>(static_cast<int>(lhs) | static_cast<int>(rhs));
206 }
207
208 enum MODE
209 {
210 LOCAL,
211 WORLD
212 };
213
214 KARMAGUI_API bool Manipulate(const float* view, const float* projection, OPERATION operation, MODE mode, float* matrix, float* deltaMatrix = NULL, const float* snap = NULL, const float* localBounds = NULL, const float* boundsSnap = NULL);
215 //
216 // Please note that this cubeview is patented by Autodesk : https://patents.google.com/patent/US7782319B2/en
217 // It seems to be a defensive patent in the US. I don't think it will bring troubles using it as
218 // other software are using the same mechanics. But just in case, you are now warned!
219 //
220 KARMAGUI_API void ViewManipulate(float* view, float length, KGVec2 position, KGVec2 size, KGU32 backgroundColor);
221
222 // use this version if you did not call Manipulate before and you are just using ViewManipulate
223 KARMAGUI_API void ViewManipulate(float* view, const float* projection, OPERATION operation, MODE mode, float* matrix, float length, KGVec2 position, KGVec2 size, KGU32 backgroundColor);
224
225 KARMAGUI_API void SetAlternativeWindow(KGGuiWindow* window);
226
227 [[deprecated("Use PushID/PopID instead.")]]
228 KARMAGUI_API void SetID(int id);
229
230 // ID stack/scopes
231 // Read the FAQ (docs/FAQ.md or http://dearimgui.org/faq) for more details about how ID are handled in dear imgui.
232 // - Those questions are answered and impacted by understanding of the ID stack system:
233 // - "Q: Why is my widget not reacting when I click on it?"
234 // - "Q: How can I have widgets with an empty label?"
235 // - "Q: How can I have multiple widgets with the same label?"
236 // - Short version: ID are hashes of the entire ID stack. If you are creating widgets in a loop you most likely
237 // want to push a unique identifier (e.g. object pointer, loop index) to uniquely differentiate them.
238 // - You can also use the "Label##foobar" syntax within widget label to distinguish them from each others.
239 // - In this header file we use the "label"/"name" terminology to denote a string that will be displayed + used as an ID,
240 // whereas "str_id" denote a string that is only used as an ID and not normally displayed.
241 KARMAGUI_API void PushID(const char* str_id); // push string into the ID stack (will hash string).
242 KARMAGUI_API void PushID(const char* str_id_begin, const char* str_id_end); // push string into the ID stack (will hash string).
243 KARMAGUI_API void PushID(const void* ptr_id); // push pointer into the ID stack (will hash pointer).
244 KARMAGUI_API void PushID(int int_id); // push integer into the ID stack (will hash integer).
245 KARMAGUI_API void PopID(); // pop from the ID stack.
246 KARMAGUI_API KGGuiID GetID(const char* str_id); // calculate unique ID (hash of whole ID stack + given parameter). e.g. if you want to query into ImGuiStorage yourself
247 KARMAGUI_API KGGuiID GetID(const char* str_id_begin, const char* str_id_end);
248 KARMAGUI_API KGGuiID GetID(const void* ptr_id);
249
250 // return true if the cursor is over the operation's gizmo
251 KARMAGUI_API bool IsOver(OPERATION op);
252 KARMAGUI_API void SetGizmoSizeClipSpace(float value);
253
254 // Allow axis to flip
255 // When true (default), the guizmo axis flip for better visibility
256 // When false, they always stay along the positive world/local axis
257 KARMAGUI_API void AllowAxisFlip(bool value);
258
259 // Configure the limit where axis are hidden
260 KARMAGUI_API void SetAxisLimit(float value);
261 // Set an axis mask to permanently hide a given axis (true -> hidden, false -> shown)
262 KARMAGUI_API void SetAxisMask(bool x, bool y, bool z);
263 // Configure the limit where planes are hiden
264 KARMAGUI_API void SetPlaneLimit(float value);
265 // from a x,y,z point in space and using Manipulation view/projection matrix, check if mouse is in pixel radius distance of that projected point
266 KARMAGUI_API bool IsOver(float* position, float pixelRadius);
267
268 enum COLOR
269 {
270 DIRECTION_X, // directionColor[0]
271 DIRECTION_Y, // directionColor[1]
272 DIRECTION_Z, // directionColor[2]
273 PLANE_X, // planeColor[0]
274 PLANE_Y, // planeColor[1]
275 PLANE_Z, // planeColor[2]
276 SELECTION, // selectionColor
277 INACTIVE, // inactiveColor
278 TRANSLATION_LINE, // translationLineColor
279 SCALE_LINE,
280 ROTATION_USING_BORDER,
281 ROTATION_USING_FILL,
282 HATCHED_AXIS_LINES,
283 TEXT,
284 TEXT_SHADOW,
285 COUNT
286 };
287
288 struct Style
289 {
290 KARMAGUI_API Style();
291
292 float TranslationLineThickness; // Thickness of lines for translation gizmo
293 float TranslationLineArrowSize; // Size of arrow at the end of lines for translation gizmo
294 float RotationLineThickness; // Thickness of lines for rotation gizmo
295 float RotationOuterLineThickness; // Thickness of line surrounding the rotation gizmo
296 float ScaleLineThickness; // Thickness of lines for scale gizmo
297 float ScaleLineCircleSize; // Size of circle at the end of lines for scale gizmo
298 float HatchedAxisLineThickness; // Thickness of hatched axis lines
299 float CenterCircleSize; // Size of circle at the center of the translate/scale gizmo
300
301 KGVec4 Colors[COLOR::COUNT];
302 };
303
304 KARMAGUI_API Style& GetStyle();
305}
This file constains KarmaGui class. The chief class for our UI needs..
Definition KarmaGuizmo.h:289
Definition KarmaGuiInternal.h:2264
Definition KarmaGui.h:163
Definition KarmaGui.h:1952