27#define IMGUI_DEFINE_MATH_OPERATORS
29#include <imgui_internal.h>
32#if defined(_MSC_VER) || defined(__MINGW32__)
35#if !defined(_MSC_VER) && !defined(__MINGW64_VERSION_MAJOR)
36#define _malloca(x) alloca(x)
45 static const float ZPI = 3.14159265358979323846f;
52 return static_cast<OPERATION>(
static_cast<int>(lhs) &
static_cast<int>(rhs));
57 return static_cast<int>(lhs) != rhs;
62 return static_cast<int>(lhs) == rhs;
67 return (lhs & rhs) != 0;
73 return (lhs & rhs) == rhs;
81 r[0] = a[0] * b[0] + a[1] * b[4] + a[2] * b[8] + a[3] * b[12];
82 r[1] = a[0] * b[1] + a[1] * b[5] + a[2] * b[9] + a[3] * b[13];
83 r[2] = a[0] * b[2] + a[1] * b[6] + a[2] * b[10] + a[3] * b[14];
84 r[3] = a[0] * b[3] + a[1] * b[7] + a[2] * b[11] + a[3] * b[15];
86 r[4] = a[4] * b[0] + a[5] * b[4] + a[6] * b[8] + a[7] * b[12];
87 r[5] = a[4] * b[1] + a[5] * b[5] + a[6] * b[9] + a[7] * b[13];
88 r[6] = a[4] * b[2] + a[5] * b[6] + a[6] * b[10] + a[7] * b[14];
89 r[7] = a[4] * b[3] + a[5] * b[7] + a[6] * b[11] + a[7] * b[15];
91 r[8] = a[8] * b[0] + a[9] * b[4] + a[10] * b[8] + a[11] * b[12];
92 r[9] = a[8] * b[1] + a[9] * b[5] + a[10] * b[9] + a[11] * b[13];
93 r[10] = a[8] * b[2] + a[9] * b[6] + a[10] * b[10] + a[11] * b[14];
94 r[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11] * b[15];
96 r[12] = a[12] * b[0] + a[13] * b[4] + a[14] * b[8] + a[15] * b[12];
97 r[13] = a[12] * b[1] + a[13] * b[5] + a[14] * b[9] + a[15] * b[13];
98 r[14] = a[12] * b[2] + a[13] * b[6] + a[14] * b[10] + a[15] * b[14];
99 r[15] = a[12] * b[3] + a[13] * b[7] + a[14] * b[11] + a[15] * b[15];
102 void Frustum(
float left,
float right,
float bottom,
float top,
float znear,
float zfar,
float* m16)
104 float temp, temp2, temp3, temp4;
106 temp2 = right - left;
107 temp3 = top - bottom;
108 temp4 = zfar - znear;
109 m16[0] = temp / temp2;
114 m16[5] = temp / temp3;
117 m16[8] = (right + left) / temp2;
118 m16[9] = (top + bottom) / temp3;
119 m16[10] = (-zfar - znear) / temp4;
123 m16[14] = (-temp * zfar) / temp4;
127 void Perspective(
float fovyInDegrees,
float aspectRatio,
float znear,
float zfar,
float* m16)
130 ymax = znear * tanf(fovyInDegrees *
DEG2RAD);
131 xmax = ymax * aspectRatio;
132 Frustum(-xmax, xmax, -ymax, ymax, znear, zfar, m16);
135 void Cross(
const float* a,
const float* b,
float* r)
137 r[0] = a[1] * b[2] - a[2] * b[1];
138 r[1] = a[2] * b[0] - a[0] * b[2];
139 r[2] = a[0] * b[1] - a[1] * b[0];
142 float Dot(
const float* a,
const float* b)
144 return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
149 float il = 1.f / (sqrtf(
Dot(a, a)) + FLT_EPSILON);
155 void LookAt(
const float* eye,
const float* at,
const float* up,
float* m16)
157 float X[3], Y[3], Z[3], tmp[3];
159 tmp[0] = eye[0] - at[0];
160 tmp[1] = eye[1] - at[1];
161 tmp[2] = eye[2] - at[2];
181 m16[12] = -
Dot(X, eye);
182 m16[13] = -
Dot(Y, eye);
183 m16[14] = -
Dot(Z, eye);
187 template <
typename T>
T Clamp(
T x,
T y,
T z) {
return ((x < y) ? y : ((x > z) ? z : x)); }
188 template <
typename T>
T max(
T x,
T y) {
return (x > y) ? x : y; }
189 template <
typename T>
T min(
T x,
T y) {
return (x < y) ? x : y; }
190 template <
typename T>
bool IsWithin(
T x,
T y,
T z) {
return (x >= y) && (x <= z); }
207 void Set(
float _x,
float _y,
float _z = 0.f,
float _w = 0.f) {
x = _x;
y = _y;
z = _z;
w = _w; }
230 res.
x =
y * v.
z -
z * v.
y;
231 res.
y =
z * v.
x -
x * v.
z;
232 res.
z =
x * v.
y -
y * v.
x;
242 x = v1.
y * v2.
z - v1.
z * v2.
y;
243 y = v1.
z * v2.
x - v1.
x * v2.
z;
244 z = v1.
x * v2.
y - v1.
y * v2.
x;
250 return (
x * v.
x) + (
y * v.
y) + (
z * v.
z) + (
w * v.
w);
255 return (
x * v.
x) + (
y * v.
y) + (
z * v.
z);
267 const float&
operator [] (
size_t index)
const {
return ((
float*)&
x)[index]; }
271 vec_t makeVect(
float _x,
float _y,
float _z = 0.f,
float _w = 0.f) {
vec_t res; res.
x = _x; res.
y = _y; res.
z = _z; res.
w = _w;
return res; }
284 res.
x = v1.
y * v2.
z - v1.
z * v2.
y;
285 res.
y = v1.
z * v2.
x - v1.
x * v2.
z;
286 res.
z = v1.
x * v2.
y - v1.
y * v2.
x;
293 return (v1.
x * v2.
x) + (v1.
y * v2.
y) + (v1.
z * v2.
z);
300 res.
w = normal.
Dot(p_point1);
325 operator float* () {
return m16; }
326 operator const float* ()
const {
return m16; }
331 v.right.Set(1.f, 0.f, 0.f, 0.f);
332 v.up.Set(0.f, 1.f, 0.f, 0.f);
333 v.dir.Set(0.f, 0.f, 1.f, 0.f);
334 v.position.Set(vt.
x, vt.
y, vt.
z, 1.f);
337 void Scale(
float _x,
float _y,
float _z)
339 v.right.Set(_x, 0.f, 0.f, 0.f);
340 v.up.Set(0.f, _y, 0.f, 0.f);
341 v.dir.Set(0.f, 0.f, _z, 0.f);
342 v.position.Set(0.f, 0.f, 0.f, 1.f);
376 return m[0][0] *
m[1][1] *
m[2][2] +
m[0][1] *
m[1][2] *
m[2][0] +
m[0][2] *
m[1][0] *
m[2][1] -
377 m[0][2] *
m[1][1] *
m[2][0] -
m[0][1] *
m[1][0] *
m[2][2] -
m[0][0] *
m[1][2] *
m[2][1];
383 v.right.Set(1.f, 0.f, 0.f, 0.f);
384 v.up.Set(0.f, 1.f, 0.f, 0.f);
385 v.dir.Set(0.f, 0.f, 1.f, 0.f);
386 v.position.Set(0.f, 0.f, 0.f, 1.f);
391 for (
int l = 0; l < 4; l++)
393 for (
int c = 0; c < 4; c++)
395 tmpm.
m[l][c] =
m[c][l];
415 out.
x =
x * matrix.
m[0][0] +
y * matrix.
m[1][0] +
z * matrix.
m[2][0] +
w * matrix.
m[3][0];
416 out.
y =
x * matrix.
m[0][1] +
y * matrix.
m[1][1] +
z * matrix.
m[2][1] +
w * matrix.
m[3][1];
417 out.
z =
x * matrix.
m[0][2] +
y * matrix.
m[1][2] +
z * matrix.
m[2][2] +
w * matrix.
m[3][2];
418 out.
w =
x * matrix.
m[0][3] +
y * matrix.
m[1][3] +
z * matrix.
m[2][3] +
w * matrix.
m[3][3];
436 out.
x =
x * matrix.
m[0][0] +
y * matrix.
m[1][0] +
z * matrix.
m[2][0] + matrix.
m[3][0];
437 out.
y =
x * matrix.
m[0][1] +
y * matrix.
m[1][1] +
z * matrix.
m[2][1] + matrix.
m[3][1];
438 out.
z =
x * matrix.
m[0][2] +
y * matrix.
m[1][2] +
z * matrix.
m[2][2] + matrix.
m[3][2];
439 out.
w =
x * matrix.
m[0][3] +
y * matrix.
m[1][3] +
z * matrix.
m[2][3] + matrix.
m[3][3];
451 out.
x =
x * matrix.
m[0][0] +
y * matrix.
m[1][0] +
z * matrix.
m[2][0];
452 out.
y =
x * matrix.
m[0][1] +
y * matrix.
m[1][1] +
z * matrix.
m[2][1];
453 out.
z =
x * matrix.
m[0][2] +
y * matrix.
m[1][2] +
z * matrix.
m[2][2];
454 out.
w =
x * matrix.
m[0][3] +
y * matrix.
m[1][3] +
z * matrix.
m[2][3];
470 m[0][0] = (srcMatrix.
m[1][1] * srcMatrix.
m[2][2] - srcMatrix.
m[1][2] * srcMatrix.
m[2][1]) * s;
471 m[0][1] = (srcMatrix.
m[2][1] * srcMatrix.
m[0][2] - srcMatrix.
m[2][2] * srcMatrix.
m[0][1]) * s;
472 m[0][2] = (srcMatrix.
m[0][1] * srcMatrix.
m[1][2] - srcMatrix.
m[0][2] * srcMatrix.
m[1][1]) * s;
473 m[1][0] = (srcMatrix.
m[1][2] * srcMatrix.
m[2][0] - srcMatrix.
m[1][0] * srcMatrix.
m[2][2]) * s;
474 m[1][1] = (srcMatrix.
m[2][2] * srcMatrix.
m[0][0] - srcMatrix.
m[2][0] * srcMatrix.
m[0][2]) * s;
475 m[1][2] = (srcMatrix.
m[0][2] * srcMatrix.
m[1][0] - srcMatrix.
m[0][0] * srcMatrix.
m[1][2]) * s;
476 m[2][0] = (srcMatrix.
m[1][0] * srcMatrix.
m[2][1] - srcMatrix.
m[1][1] * srcMatrix.
m[2][0]) * s;
477 m[2][1] = (srcMatrix.
m[2][0] * srcMatrix.
m[0][1] - srcMatrix.
m[2][1] * srcMatrix.
m[0][0]) * s;
478 m[2][2] = (srcMatrix.
m[0][0] * srcMatrix.
m[1][1] - srcMatrix.
m[0][1] * srcMatrix.
m[1][0]) * s;
479 m[3][0] = -(
m[0][0] * srcMatrix.
m[3][0] +
m[1][0] * srcMatrix.
m[3][1] +
m[2][0] * srcMatrix.
m[3][2]);
480 m[3][1] = -(
m[0][1] * srcMatrix.
m[3][0] +
m[1][1] * srcMatrix.
m[3][1] +
m[2][1] * srcMatrix.
m[3][2]);
481 m[3][2] = -(
m[0][2] * srcMatrix.
m[3][0] +
m[1][2] * srcMatrix.
m[3][1] +
m[2][2] * srcMatrix.
m[3][2]);
487 for (
int i = 0; i < 4; ++i)
489 src[i] = srcMatrix.
m16[i * 4];
490 src[i + 4] = srcMatrix.
m16[i * 4 + 1];
491 src[i + 8] = srcMatrix.
m16[i * 4 + 2];
492 src[i + 12] = srcMatrix.
m16[i * 4 + 3];
497 tmp[0] = src[10] * src[15];
498 tmp[1] = src[11] * src[14];
499 tmp[2] = src[9] * src[15];
500 tmp[3] = src[11] * src[13];
501 tmp[4] = src[9] * src[14];
502 tmp[5] = src[10] * src[13];
503 tmp[6] = src[8] * src[15];
504 tmp[7] = src[11] * src[12];
505 tmp[8] = src[8] * src[14];
506 tmp[9] = src[10] * src[12];
507 tmp[10] = src[8] * src[13];
508 tmp[11] = src[9] * src[12];
511 m16[0] = (tmp[0] * src[5] + tmp[3] * src[6] + tmp[4] * src[7]) - (tmp[1] * src[5] + tmp[2] * src[6] + tmp[5] * src[7]);
512 m16[1] = (tmp[1] * src[4] + tmp[6] * src[6] + tmp[9] * src[7]) - (tmp[0] * src[4] + tmp[7] * src[6] + tmp[8] * src[7]);
513 m16[2] = (tmp[2] * src[4] + tmp[7] * src[5] + tmp[10] * src[7]) - (tmp[3] * src[4] + tmp[6] * src[5] + tmp[11] * src[7]);
514 m16[3] = (tmp[5] * src[4] + tmp[8] * src[5] + tmp[11] * src[6]) - (tmp[4] * src[4] + tmp[9] * src[5] + tmp[10] * src[6]);
515 m16[4] = (tmp[1] * src[1] + tmp[2] * src[2] + tmp[5] * src[3]) - (tmp[0] * src[1] + tmp[3] * src[2] + tmp[4] * src[3]);
516 m16[5] = (tmp[0] * src[0] + tmp[7] * src[2] + tmp[8] * src[3]) - (tmp[1] * src[0] + tmp[6] * src[2] + tmp[9] * src[3]);
517 m16[6] = (tmp[3] * src[0] + tmp[6] * src[1] + tmp[11] * src[3]) - (tmp[2] * src[0] + tmp[7] * src[1] + tmp[10] * src[3]);
518 m16[7] = (tmp[4] * src[0] + tmp[9] * src[1] + tmp[10] * src[2]) - (tmp[5] * src[0] + tmp[8] * src[1] + tmp[11] * src[2]);
521 tmp[0] = src[2] * src[7];
522 tmp[1] = src[3] * src[6];
523 tmp[2] = src[1] * src[7];
524 tmp[3] = src[3] * src[5];
525 tmp[4] = src[1] * src[6];
526 tmp[5] = src[2] * src[5];
527 tmp[6] = src[0] * src[7];
528 tmp[7] = src[3] * src[4];
529 tmp[8] = src[0] * src[6];
530 tmp[9] = src[2] * src[4];
531 tmp[10] = src[0] * src[5];
532 tmp[11] = src[1] * src[4];
535 m16[8] = (tmp[0] * src[13] + tmp[3] * src[14] + tmp[4] * src[15]) - (tmp[1] * src[13] + tmp[2] * src[14] + tmp[5] * src[15]);
536 m16[9] = (tmp[1] * src[12] + tmp[6] * src[14] + tmp[9] * src[15]) - (tmp[0] * src[12] + tmp[7] * src[14] + tmp[8] * src[15]);
537 m16[10] = (tmp[2] * src[12] + tmp[7] * src[13] + tmp[10] * src[15]) - (tmp[3] * src[12] + tmp[6] * src[13] + tmp[11] * src[15]);
538 m16[11] = (tmp[5] * src[12] + tmp[8] * src[13] + tmp[11] * src[14]) - (tmp[4] * src[12] + tmp[9] * src[13] + tmp[10] * src[14]);
539 m16[12] = (tmp[2] * src[10] + tmp[5] * src[11] + tmp[1] * src[9]) - (tmp[4] * src[11] + tmp[0] * src[9] + tmp[3] * src[10]);
540 m16[13] = (tmp[8] * src[11] + tmp[0] * src[8] + tmp[7] * src[10]) - (tmp[6] * src[10] + tmp[9] * src[11] + tmp[1] * src[8]);
541 m16[14] = (tmp[6] * src[9] + tmp[11] * src[11] + tmp[3] * src[8]) - (tmp[10] * src[11] + tmp[2] * src[8] + tmp[7] * src[9]);
542 m16[15] = (tmp[10] * src[10] + tmp[4] * src[8] + tmp[9] * src[9]) - (tmp[8] * src[9] + tmp[11] * src[10] + tmp[5] * src[8]);
545 det = src[0] *
m16[0] + src[1] *
m16[1] + src[2] *
m16[2] + src[3] *
m16[3];
548 float invdet = 1 / det;
549 for (
int j = 0; j < 16; ++j)
560 float length2 = axis.LengthSq();
561 if (length2 < FLT_EPSILON)
567 vec_t n = axis * (1.f / sqrtf(length2));
568 float s = sinf(angle);
569 float c = cosf(angle);
572 float xx = n.
x * n.
x * k + c;
573 float yy = n.
y * n.
y * k + c;
574 float zz = n.
z * n.
z * k + c;
575 float xy = n.
x * n.
y * k;
576 float yz = n.
y * n.
z * k;
577 float zx = n.
z * n.
x * k;
737 static const ImU32
directionColor[3] = { IM_COL32(0xAA, 0, 0, 0xFF), IM_COL32(0, 0xAA, 0, 0xFF), IM_COL32(0, 0, 0xAA, 0XFF) };
740 static const ImU32
planeColor[3] = { IM_COL32(0xAA, 0, 0, 0x61), IM_COL32(0, 0xAA, 0, 0x61), IM_COL32(0, 0, 0xAA, 0x61) };
745 "Y : %5.3f Z : %5.3f",
"X : %5.3f Z : %5.3f",
"X : %5.3f Y : %5.3f",
746 "X : %5.3f Y : %5.3f Z : %5.3f" };
747 static const char*
scaleInfoMask[] = {
"X : %5.2f",
"Y : %5.2f",
"Z : %5.2f",
"XYZ : %5.2f" };
748 static const char*
rotationInfoMask[] = {
"X : %5.2f deg %5.2f rad",
"Y : %5.2f deg %5.2f rad",
"Z : %5.2f deg %5.2f rad",
"Screen : %5.2f deg %5.2f rad" };
749 static const int translationInfoIndex[] = { 0,0,0, 1,0,0, 2,0,0, 1,2,0, 0,2,0, 0,1,0, 0,1,2 };
766 trans *= 0.5f / trans.
w;
768 trans.
y = 1.f - trans.
y;
771 trans.
x += position.x;
772 trans.
y += position.y;
773 return ImVec2(trans.
x, trans.
y);
778 ImGuiIO& io = ImGui::GetIO();
783 const float mox = ((io.MousePos.x - position.x) / size.x) * 2.f - 1.f;
784 const float moy = (1.f - ((io.MousePos.y - position.y) / size.y)) * 2.f - 1.f;
786 const float zNear =
gContext.mReversed ? (1.f - FLT_EPSILON) : 0.f;
787 const float zFar =
gContext.mReversed ? 0.f : (1.f - FLT_EPSILON);
790 rayOrigin *= 1.f / rayOrigin.
w;
793 rayEnd *= 1.f / rayEnd.
w;
799 vec_t startOfSegment = start;
801 if (fabsf(startOfSegment.
w) > FLT_EPSILON)
803 startOfSegment *= 1.f / startOfSegment.
w;
806 vec_t endOfSegment = end;
808 if (fabsf(endOfSegment.
w) > FLT_EPSILON)
810 endOfSegment *= 1.f / endOfSegment.
w;
813 vec_t clipSpaceAxis = endOfSegment - startOfSegment;
814 clipSpaceAxis.
y /=
gContext.mDisplayRatio;
815 float segmentLengthInClipSpace = sqrtf(clipSpaceAxis.
x * clipSpaceAxis.
x + clipSpaceAxis.
y * clipSpaceAxis.
y);
816 return segmentLengthInClipSpace;
821 vec_t pts[] = { ptO, ptA, ptB };
822 for (
unsigned int i = 0; i < 3; i++)
825 if (fabsf(pts[i].w) > FLT_EPSILON)
827 pts[i] *= 1.f / pts[i].
w;
830 vec_t segA = pts[1] - pts[0];
831 vec_t segB = pts[2] - pts[0];
836 float dt = segAOrtho.
Dot3(segB);
837 float surface = sqrtf(segA.
x * segA.
x + segA.
y * segA.
y) * fabsf(dt);
843 vec_t c = point - vertPos1;
846 V.Normalize(vertPos2 - vertPos1);
847 float d = (vertPos2 - vertPos1).Length();
860 return vertPos1 +
V * t;
865 float numer = plan.
Dot3(rOrigin) - plan.
w;
866 float denom = plan.
Dot3(rVector);
868 if (fabsf(denom) < FLT_EPSILON)
873 return -(numer / denom);
878 return plan.
Dot3(point) + plan.
w;
886 void SetRect(
float x,
float y,
float width,
float height)
894 gContext.mDisplayRatio = width / height;
899 gContext.mIsOrthographic = isOrthographic;
904 gContext.mDrawList = drawlist ? drawlist : ImGui::GetWindowDrawList();
909 ImGui::SetCurrentContext(ctx);
914 const ImU32 flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoBringToFrontOnFocus;
916#ifdef IMGUI_HAS_VIEWPORT
917 ImGui::SetNextWindowSize(ImGui::GetMainViewport()->Size);
918 ImGui::SetNextWindowPos(ImGui::GetMainViewport()->Pos);
920 ImGuiIO& io = ImGui::GetIO();
921 ImGui::SetNextWindowSize(io.DisplaySize);
922 ImGui::SetNextWindowPos(ImVec2(0, 0));
925 ImGui::PushStyleColor(ImGuiCol_WindowBg, 0);
926 ImGui::PushStyleColor(ImGuiCol_Border, 0);
927 ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
929 ImGui::Begin(
"gizmo", NULL, flags);
930 gContext.mDrawList = ImGui::GetWindowDrawList();
932 ImGui::PopStyleVar();
933 ImGui::PopStyleColor(2);
1010 vec_t nearPos, farPos;
1014 gContext.mReversed = (nearPos.
z/nearPos.
w) > (farPos.
z / farPos.
w);
1027 gContext.mScreenSquareCenter = centerSSpace;
1028 gContext.mScreenSquareMin = ImVec2(centerSSpace.x - 10.f, centerSSpace.y - 10.f);
1029 gContext.mScreenSquareMax = ImVec2(centerSSpace.x + 10.f, centerSSpace.y + 10.f);
1042 for (
int i = 0; i < 3; i++)
1051 for (
int i = 0; i < 3; i++)
1058 for (
int i = 0; i < 3; i++)
1070 for (
int i = 0; i < 7; i++)
1086 belowAxisLimit =
gContext.mBelowAxisLimit[axisIndex];
1087 belowPlaneLimit =
gContext.mBelowPlaneLimit[axisIndex];
1089 dirAxis *=
gContext.mAxisFactor[axisIndex];
1090 dirPlaneX *=
gContext.mAxisFactor[(axisIndex + 1) % 3];
1091 dirPlaneY *=
gContext.mAxisFactor[(axisIndex + 2) % 3];
1106 bool & allowFlip =
gContext.mAllowAxisFlip;
1107 float mulAxis = (allowFlip && lenDir < lenDirMinus&& fabsf(lenDir - lenDirMinus) > FLT_EPSILON) ? -1.f : 1.f;
1108 float mulAxisX = (allowFlip && lenDirPlaneX < lenDirMinusPlaneX&& fabsf(lenDirPlaneX - lenDirMinusPlaneX) > FLT_EPSILON) ? -1.f : 1.f;
1109 float mulAxisY = (allowFlip && lenDirPlaneY < lenDirMinusPlaneY&& fabsf(lenDirPlaneY - lenDirMinusPlaneY) > FLT_EPSILON) ? -1.f : 1.f;
1111 dirPlaneX *= mulAxisX;
1112 dirPlaneY *= mulAxisY;
1118 belowPlaneLimit = (paraSurf > 0.0025f);
1119 belowAxisLimit = (axisLengthInClipSpace > 0.02f);
1122 gContext.mAxisFactor[axisIndex] = mulAxis;
1123 gContext.mAxisFactor[(axisIndex + 1) % 3] = mulAxisX;
1124 gContext.mAxisFactor[(axisIndex + 2) % 3] = mulAxisY;
1125 gContext.mBelowAxisLimit[axisIndex] = belowAxisLimit;
1126 gContext.mBelowPlaneLimit[axisIndex] = belowPlaneLimit;
1132 if (snap <= FLT_EPSILON)
1137 float modulo = fmodf(*value, snap);
1138 float moduloRatio = fabsf(modulo) / snap;
1145 *value = *value - modulo + snap * ((*value < 0.f) ? -1.f : 1.f);
1150 for (
int i = 0; i < 3; i++)
1161 vec_t perpendicularVector;
1164 float acosAngle =
Clamp(
Dot(localPos,
gContext.mRotationVectorSource), -1.f, 1.f);
1165 float angle = acosf(acosAngle);
1166 angle *= (
Dot(localPos, perpendicularVector) < 0.f) ? 1.f : -1.f;
1176 ImDrawList* drawList =
gContext.mDrawList;
1182 vec_t cameraToModelNormalized;
1187 cameraToModelNormalized = viewInverse.
v.
dir;
1199 int circleMul = hasRSC ? 1 : 2;
1200 for (
int axis = 0; axis < 3; axis++)
1208 float angleStart = atan2f(cameraToModelNormalized[(4 - axis) % 3], cameraToModelNormalized[(3 - axis) % 3]) +
ZPI * 0.5f;
1214 vec_t pos =
makeVect(axisPos[axis], axisPos[(axis + 1) % 3], axisPos[(axis + 2) % 3]) *
gContext.mScreenFactor;
1219 if (radiusAxis >
gContext.mRadiusSquareCenter)
1221 gContext.mRadiusSquareCenter = radiusAxis;
1249 ImVec2 destinationPosOnScreen = circlePos[1];
1252 drawList->AddText(ImVec2(destinationPosOnScreen.x + 15, destinationPosOnScreen.y + 15), IM_COL32_BLACK, tmps);
1253 drawList->AddText(ImVec2(destinationPosOnScreen.x + 14, destinationPosOnScreen.y + 14), IM_COL32_WHITE, tmps);
1259 for (
int j = 1; j < 10; j++)
1263 gContext.mDrawList->AddLine(baseSSpace2, worldDirSSpace2, IM_COL32(0, 0, 0, 0x80), 6.f);
1269 ImDrawList* drawList =
gContext.mDrawList;
1281 vec_t scaleDisplay = { 1.f, 1.f, 1.f, 1.f };
1288 for (
unsigned int i = 0; i < 3; i++)
1294 vec_t dirPlaneX, dirPlaneY, dirAxis;
1295 bool belowAxisLimit, belowPlaneLimit;
1302 float markerScale = hasTranslateOnAxis ? 1.4f : 1.0f;
1309 drawList->AddLine(baseSSpace, worldDirSSpaceNoScale, IM_COL32(0x40, 0x40, 0x40, 0xFF), 3.f);
1310 drawList->AddCircleFilled(worldDirSSpaceNoScale, 6.f, IM_COL32(0x40, 0x40, 0x40, 0xFF));
1313 if(!hasTranslateOnAxis ||
gContext.mbUsing)
1315 drawList->AddLine(baseSSpace, worldDirSSpace, colors[i + 1], 3.f);
1317 drawList->AddCircleFilled(worldDirSSpace, 6.f, colors[i + 1]);
1327 drawList->AddCircleFilled(
gContext.mScreenSquareCenter, 6.f, colors[0], 32);
1342 int componentInfoIndex = (type -
MT_SCALE_X) * 3;
1344 drawList->AddText(ImVec2(destinationPosOnScreen.x + 15, destinationPosOnScreen.y + 15), IM_COL32_BLACK, tmps);
1345 drawList->AddText(ImVec2(destinationPosOnScreen.x + 14, destinationPosOnScreen.y + 14), IM_COL32_WHITE, tmps);
1352 ImDrawList* drawList =
gContext.mDrawList;
1370 bool belowAxisLimit =
false;
1371 bool belowPlaneLimit =
false;
1372 for (
unsigned int i = 0; i < 3; ++i)
1374 vec_t dirPlaneX, dirPlaneY, dirAxis;
1383 drawList->AddLine(baseSSpace, worldDirSSpace, colors[i + 1], 3.f);
1386 ImVec2 dir(origin - worldDirSSpace);
1388 float d = sqrtf(ImLengthSqr(dir));
1392 ImVec2 ortogonalDir(dir.y, -dir.x);
1393 ImVec2 a(worldDirSSpace + dir);
1394 drawList->AddTriangleFilled(worldDirSSpace - dir, a + ortogonalDir, a - ortogonalDir, colors[i + 1]);
1406 ImVec2 screenQuadPts[4];
1407 for (
int j = 0; j < 4; ++j)
1412 drawList->AddPolyline(screenQuadPts, 4,
directionColor[i],
true, 1.0f);
1413 drawList->AddConvexPolyFilled(screenQuadPts, 4, colors[i + 4]);
1417 drawList->AddCircleFilled(
gContext.mScreenSquareCenter, 6.f, colors[0], 32);
1423 vec_t dif = { destinationPosOnScreen.x - sourcePosOnScreen.x, destinationPosOnScreen.y - sourcePosOnScreen.y, 0.f, 0.f };
1428 drawList->AddLine(ImVec2(sourcePosOnScreen.x + dif.
x, sourcePosOnScreen.y + dif.
y), ImVec2(destinationPosOnScreen.x - dif.
x, destinationPosOnScreen.y - dif.
y),
translationLineColor, 2.f);
1432 int componentInfoIndex = (type -
MT_MOVE_X) * 3;
1434 drawList->AddText(ImVec2(destinationPosOnScreen.x + 15, destinationPosOnScreen.y + 15), IM_COL32_BLACK, tmps);
1435 drawList->AddText(ImVec2(destinationPosOnScreen.x + 14, destinationPosOnScreen.y + 14), IM_COL32_WHITE, tmps);
1441 if (ImGui::IsMouseClicked(0) && !ImGui::IsAnyItemHovered() && !ImGui::IsAnyItemActive())
1450 ImGuiIO& io = ImGui::GetIO();
1451 ImDrawList* drawList =
gContext.mDrawList;
1454 vec_t axesWorldDirections[3];
1455 vec_t bestAxisWorldDirection = { 0.0f, 0.0f, 0.0f, 0.0f };
1457 unsigned int numAxes = 1;
1458 axes[0] =
gContext.mBoundsBestAxis;
1459 int bestAxis = axes[0];
1463 float bestDot = 0.f;
1464 for (
unsigned int i = 0; i < 3; i++)
1466 vec_t dirPlaneNormalWorld;
1475 bestAxisWorldDirection = dirPlaneNormalWorld;
1481 axesWorldDirections[numAxes] = dirPlaneNormalWorld;
1490 axesWorldDirections[0] = bestAxisWorldDirection;
1494 else if (bestAxis != axes[0])
1496 unsigned int bestIndex = 0;
1497 for (
unsigned int i = 0; i < numAxes; i++)
1499 if (axes[i] == bestAxis)
1505 int tempAxis = axes[0];
1506 axes[0] = axes[bestIndex];
1507 axes[bestIndex] = tempAxis;
1508 vec_t tempDirection = axesWorldDirections[0];
1509 axesWorldDirections[0] = axesWorldDirections[bestIndex];
1510 axesWorldDirections[bestIndex] = tempDirection;
1513 for (
unsigned int axisIndex = 0; axisIndex < numAxes; ++axisIndex)
1515 bestAxis = axes[axisIndex];
1516 bestAxisWorldDirection = axesWorldDirections[axisIndex];
1521 int secondAxis = (bestAxis + 1) % 3;
1522 int thirdAxis = (bestAxis + 2) % 3;
1524 for (
int i = 0; i < 4; i++)
1526 aabb[i][3] = aabb[i][bestAxis] = 0.f;
1527 aabb[i][secondAxis] = bounds[secondAxis + 3 * (i >> 1)];
1528 aabb[i][thirdAxis] = bounds[thirdAxis + 3 * ((i >> 1) ^ (i & 1))];
1532 unsigned int anchorAlpha =
gContext.mbEnable ? IM_COL32_BLACK : IM_COL32(0, 0, 0, 0x80);
1535 for (
int i = 0; i < 4; i++)
1537 ImVec2 worldBound1 =
worldToPos(aabb[i], boundsMVP);
1538 ImVec2 worldBound2 =
worldToPos(aabb[(i + 1) % 4], boundsMVP);
1543 float boundDistance = sqrtf(ImLengthSqr(worldBound1 - worldBound2));
1544 int stepCount = (int)(boundDistance / 10.f);
1545 stepCount =
min(stepCount, 1000);
1546 float stepLength = 1.f / (float)stepCount;
1547 for (
int j = 0; j < stepCount; j++)
1549 float t1 = (float)j * stepLength;
1550 float t2 = (float)j * stepLength + stepLength * 0.5f;
1551 ImVec2 worldBoundSS1 = ImLerp(worldBound1, worldBound2, ImVec2(t1, t1));
1552 ImVec2 worldBoundSS2 = ImLerp(worldBound1, worldBound2, ImVec2(t2, t2));
1554 drawList->AddLine(worldBoundSS1, worldBoundSS2, IM_COL32(0xAA, 0xAA, 0xAA, 0) + anchorAlpha, 2.f);
1556 vec_t midPoint = (aabb[i] + aabb[(i + 1) % 4]) * 0.5f;
1557 ImVec2 midBound =
worldToPos(midPoint, boundsMVP);
1558 static const float AnchorBigRadius = 8.f;
1559 static const float AnchorSmallRadius = 6.f;
1560 bool overBigAnchor = ImLengthSqr(worldBound1 - io.MousePos) <= (AnchorBigRadius * AnchorBigRadius);
1561 bool overSmallAnchor = ImLengthSqr(midBound - io.MousePos) <= (AnchorBigRadius * AnchorBigRadius);
1564 vec_t gizmoHitProportion;
1568 type =
GetMoveType(operation, &gizmoHitProportion);
1581 overBigAnchor =
false;
1582 overSmallAnchor =
false;
1585 unsigned int bigAnchorColor = overBigAnchor ?
selectionColor : (IM_COL32(0xAA, 0xAA, 0xAA, 0) + anchorAlpha);
1586 unsigned int smallAnchorColor = overSmallAnchor ?
selectionColor : (IM_COL32(0xAA, 0xAA, 0xAA, 0) + anchorAlpha);
1588 drawList->AddCircleFilled(worldBound1, AnchorBigRadius, IM_COL32_BLACK);
1589 drawList->AddCircleFilled(worldBound1, AnchorBigRadius - 1.2f, bigAnchorColor);
1591 drawList->AddCircleFilled(midBound, AnchorSmallRadius, IM_COL32_BLACK);
1592 drawList->AddCircleFilled(midBound, AnchorSmallRadius - 1.2f, smallAnchorColor);
1593 int oppositeIndex = (i + 2) % 4;
1597 gContext.mBoundsPivot.TransformPoint(aabb[(i + 2) % 4],
gContext.mModelSource);
1600 gContext.mBoundsBestAxis = bestAxis;
1601 gContext.mBoundsAxis[0] = secondAxis;
1602 gContext.mBoundsAxis[1] = thirdAxis;
1604 gContext.mBoundsLocalPivot.Set(0.f);
1605 gContext.mBoundsLocalPivot[secondAxis] = aabb[oppositeIndex][secondAxis];
1606 gContext.mBoundsLocalPivot[thirdAxis] = aabb[oppositeIndex][thirdAxis];
1615 vec_t midPointOpposite = (aabb[(i + 2) % 4] + aabb[(i + 3) % 4]) * 0.5f;
1616 gContext.mBoundsPivot.TransformPoint(midPointOpposite,
gContext.mModelSource);
1619 gContext.mBoundsBestAxis = bestAxis;
1620 int indices[] = { secondAxis , thirdAxis };
1621 gContext.mBoundsAxis[0] = indices[i % 2];
1624 gContext.mBoundsLocalPivot.Set(0.f);
1625 gContext.mBoundsLocalPivot[
gContext.mBoundsAxis[0]] = aabb[oppositeIndex][indices[i % 2]];
1636 scale.SetToIdentity();
1647 for (
int i = 0; i < 2; i++)
1649 int axisIndex1 =
gContext.mBoundsAxis[i];
1650 if (axisIndex1 == -1)
1655 float ratioAxis = 1.f;
1656 vec_t axisDir =
gContext.mBoundsMatrix.component[axisIndex1].Abs();
1658 float dtAxis = axisDir.
Dot(referenceVector);
1659 float boundSize = bounds[axisIndex1 + 3] - bounds[axisIndex1];
1660 if (dtAxis > FLT_EPSILON)
1662 ratioAxis = axisDir.
Dot(deltaVector) / dtAxis;
1667 float length = boundSize * ratioAxis;
1669 if (boundSize > FLT_EPSILON)
1671 ratioAxis = length / boundSize;
1674 scale.component[axisIndex1] *= ratioAxis;
1687 ImFormatString(tmps,
sizeof(tmps),
"X: %.2f Y: %.2f Z:%.2f"
1688 , (bounds[3] - bounds[0]) *
gContext.mBoundsMatrix.component[0].Length() * scale.component[0].Length()
1689 , (bounds[4] - bounds[1]) *
gContext.mBoundsMatrix.component[1].Length() * scale.component[1].Length()
1690 , (bounds[5] - bounds[2]) *
gContext.mBoundsMatrix.component[2].Length() * scale.component[2].Length()
1692 drawList->AddText(ImVec2(destinationPosOnScreen.x + 15, destinationPosOnScreen.y + 15), IM_COL32_BLACK, tmps);
1693 drawList->AddText(ImVec2(destinationPosOnScreen.x + 14, destinationPosOnScreen.y + 14), IM_COL32_WHITE, tmps);
1696 if (!io.MouseDown[0]) {
1712 ImGuiIO& io = ImGui::GetIO();
1716 if (io.MousePos.x >=
gContext.mScreenSquareMin.x && io.MousePos.x <=
gContext.mScreenSquareMax.x &&
1717 io.MousePos.y >=
gContext.mScreenSquareMin.y && io.MousePos.y <=
gContext.mScreenSquareMax.y &&
1724 for (
unsigned int i = 0; i < 3 && type ==
MT_NONE; i++)
1730 vec_t dirPlaneX, dirPlaneY, dirAxis;
1731 bool belowAxisLimit, belowPlaneLimit;
1748 if ((closestPointOnAxis -
makeVect(posOnPlanScreen)).Length() < 12.f)
1758 ImGuiIO& io = ImGui::GetIO();
1761 vec_t deltaScreen = { io.MousePos.x -
gContext.mScreenSquareCenter.x, io.MousePos.y -
gContext.mScreenSquareCenter.y, 0.f, 0.f };
1762 float dist = deltaScreen.
Length();
1773 for (
unsigned int i = 0; i < 3 && type ==
MT_NONE; i++)
1784 vec_t intersectViewPos;
1787 if (ImAbs(modelViewPos.
z) - ImAbs(intersectViewPos.
z) < -FLT_EPSILON)
1792 const vec_t localPos = intersectWorldPos -
gContext.mModel.v.position;
1798 const ImVec2 distanceOnScreen = idealPosOnCircleScreen - io.MousePos;
1816 ImGuiIO& io = ImGui::GetIO();
1820 if (io.MousePos.x >=
gContext.mScreenSquareMin.x && io.MousePos.x <=
gContext.mScreenSquareMax.x &&
1821 io.MousePos.y >=
gContext.mScreenSquareMin.y && io.MousePos.y <=
gContext.mScreenSquareMax.y &&
1830 for (
unsigned int i = 0; i < 3 && type ==
MT_NONE; i++)
1832 vec_t dirPlaneX, dirPlaneY, dirAxis;
1833 bool belowAxisLimit, belowPlaneLimit;
1851 const float dx = dirPlaneX.
Dot3((posOnPlan -
gContext.mModel.v.position) * (1.f /
gContext.mScreenFactor));
1852 const float dy = dirPlaneY.
Dot3((posOnPlan -
gContext.mModel.v.position) * (1.f /
gContext.mScreenFactor));
1858 if (gizmoHitProportion)
1860 *gizmoHitProportion =
makeVect(dx, dy, 0.f);
1872 ImGuiIO& io = ImGui::GetIO();
1874 bool modified =
false;
1879 ImGui::SetNextFrameWantCaptureMouse(
true);
1892 float lengthOnAxis =
Dot(axisValue, delta);
1893 delta = axisValue * lengthOnAxis;
1900 if (applyRotationLocaly)
1904 matrix_t modelSourceNormalizedInverse;
1905 modelSourceNormalizedInverse.
Inverse(modelSourceNormalized);
1914 delta =
gContext.mMatrixOrigin + cumulativeDelta -
gContext.mModel.v.position;
1918 if (delta !=
gContext.mTranslationLastDelta)
1922 gContext.mTranslationLastDelta = delta;
1929 memcpy(deltaMatrix, deltaMatrixTranslation.
m16,
sizeof(
float) * 16);
1935 if (!io.MouseDown[0])
1945 vec_t gizmoHitProportion;
1949 ImGui::SetNextFrameWantCaptureMouse(
true);
1961 for (
unsigned int i = 0; i < 3; i++)
1963 vec_t orthoVector =
Cross(movePlanNormal[i], cameraToModelNormalized);
1964 movePlanNormal[i].
Cross(orthoVector);
1985 ImGuiIO& io = ImGui::GetIO();
1986 bool modified =
false;
1994 ImGui::SetNextFrameWantCaptureMouse(
true);
2008 gContext.mScale.Set(1.f, 1.f, 1.f);
2011 gContext.mSaveMousePosx = io.MousePos.x;
2017 ImGui::SetNextFrameWantCaptureMouse(
true);
2028 float lengthOnAxis =
Dot(axisValue, delta);
2029 delta = axisValue * lengthOnAxis;
2032 float ratio =
Dot(axisValue, baseVector + delta) /
Dot(axisValue, baseVector);
2038 float scaleDelta = (io.MousePos.x -
gContext.mSaveMousePosx) * 0.01f;
2039 gContext.mScale.Set(
max(1.f + scaleDelta, 0.001f));
2045 float scaleSnap[] = { snap[0], snap[0], snap[0] };
2050 for (
int i = 0; i < 3; i++)
2070 vec_t originalScaleDivider;
2071 originalScaleDivider.
x = 1 /
gContext.mModelScaleOrigin.x;
2072 originalScaleDivider.
y = 1 /
gContext.mModelScaleOrigin.y;
2073 originalScaleDivider.
z = 1 /
gContext.mModelScaleOrigin.z;
2075 deltaScale = deltaScale * originalScaleDivider;
2077 deltaMatrixScale.
Scale(deltaScale);
2078 memcpy(deltaMatrix, deltaMatrixScale.
m16,
sizeof(
float) * 16);
2081 if (!io.MouseDown[0])
2084 gContext.mScale.Set(1.f, 1.f, 1.f);
2098 ImGuiIO& io = ImGui::GetIO();
2100 bool modified =
false;
2108 ImGui::SetNextFrameWantCaptureMouse(
true);
2113 applyRotationLocaly =
true;
2123 if (applyRotationLocaly)
2142 ImGui::SetNextFrameWantCaptureMouse(
true);
2146 float snapInRadian = snap[0] *
DEG2RAD;
2149 vec_t rotationAxisLocalSpace;
2165 if (applyRotationLocaly)
2174 *(
matrix_t*)matrix = res * deltaRotation;
2183 if (!io.MouseDown[0])
2203 rotation[0] =
RAD2DEG * atan2f(mat.
m[1][2], mat.
m[2][2]);
2204 rotation[1] =
RAD2DEG * atan2f(-mat.
m[0][2], sqrtf(mat.
m[1][2] * mat.
m[1][2] + mat.
m[2][2] * mat.
m[2][2]));
2205 rotation[2] =
RAD2DEG * atan2f(mat.
m[0][1], mat.
m[0][0]);
2217 for (
int i = 0; i < 3; i++)
2222 mat = rot[0] * rot[1] * rot[2];
2224 float validScale[3];
2225 for (
int i = 0; i < 3; i++)
2227 if (fabsf(scale[i]) < FLT_EPSILON)
2229 validScale[i] = 0.001f;
2233 validScale[i] = scale[i];
2236 mat.
v.
right *= validScale[0];
2237 mat.
v.
up *= validScale[1];
2238 mat.
v.
dir *= validScale[2];
2239 mat.
v.
position.
Set(translation[0], translation[1], translation[2], 1.f);
2252 bool Manipulate(
const float* view,
const float* projection,
OPERATION operation,
MODE mode,
float* matrix,
float* deltaMatrix,
const float* snap,
const float* localBounds,
const float* boundsSnap)
2259 ((
matrix_t*)deltaMatrix)->SetToIdentity();
2263 vec_t camSpacePosition;
2265 if (!
gContext.mIsOrthographic && camSpacePosition.
z < 0.001f)
2272 bool manipulated =
false;
2278 HandleScale(matrix, deltaMatrix, operation, type, snap) ||
2283 if (localBounds && !
gContext.mbUsing)
2300 gContext.mGizmoSizeClipSpace = value;
2306 frustum[0].x = clip[3] - clip[0];
2307 frustum[0].y = clip[7] - clip[4];
2308 frustum[0].z = clip[11] - clip[8];
2309 frustum[0].w = clip[15] - clip[12];
2311 frustum[1].x = clip[3] + clip[0];
2312 frustum[1].y = clip[7] + clip[4];
2313 frustum[1].z = clip[11] + clip[8];
2314 frustum[1].w = clip[15] + clip[12];
2316 frustum[2].x = clip[3] + clip[1];
2317 frustum[2].y = clip[7] + clip[5];
2318 frustum[2].z = clip[11] + clip[9];
2319 frustum[2].w = clip[15] + clip[13];
2321 frustum[3].x = clip[3] - clip[1];
2322 frustum[3].y = clip[7] - clip[5];
2323 frustum[3].z = clip[11] - clip[9];
2324 frustum[3].w = clip[15] - clip[13];
2326 frustum[4].x = clip[3] - clip[2];
2327 frustum[4].y = clip[7] - clip[6];
2328 frustum[4].z = clip[11] - clip[10];
2329 frustum[4].w = clip[15] - clip[14];
2331 frustum[5].x = clip[3] + clip[2];
2332 frustum[5].y = clip[7] + clip[6];
2333 frustum[5].z = clip[11] + clip[10];
2334 frustum[5].w = clip[15] + clip[14];
2336 for (
int i = 0; i < 6; i++)
2338 frustum[i].Normalize();
2342 void DrawCubes(
const float* view,
const float* projection,
const float* matrices,
int matrixCount)
2350 ImVec2 faceCoordsScreen[4];
2353 CubeFace* faces = (CubeFace*)
_malloca(
sizeof(CubeFace) * matrixCount * 6);
2364 int cubeFaceCount = 0;
2365 for (
int cube = 0; cube < matrixCount; cube++)
2367 const float* matrix = &matrices[cube * 16];
2371 for (
int iFace = 0; iFace < 6; iFace++)
2373 const int normalIndex = (iFace % 3);
2374 const int perpXIndex = (normalIndex + 1) % 3;
2375 const int perpYIndex = (normalIndex + 2) % 3;
2376 const float invert = (iFace > 2) ? -1.f : 1.f;
2402 vec_t centerPosition, centerPositionVP;
2406 bool inFrustum =
true;
2407 for (
int iFrustum = 0; iFrustum < 6; iFrustum++)
2421 CubeFace& cubeFace = faces[cubeFaceCount];
2425 for (
unsigned int iCoord = 0; iCoord < 4; iCoord++)
2427 cubeFace.faceCoordsScreen[iCoord] =
worldToPos(faceCoords[iCoord] * 0.5f * invert, res);
2429 cubeFace.color =
directionColor[normalIndex] | IM_COL32(0x80, 0x80, 0x80, 0);
2431 cubeFace.z = centerPositionVP.
z / centerPositionVP.
w;
2435 qsort(faces, cubeFaceCount,
sizeof(CubeFace), [](
void const* _a,
void const* _b) {
2436 CubeFace* a = (CubeFace*)_a;
2437 CubeFace* b = (CubeFace*)_b;
2445 for (
int iFace = 0; iFace < cubeFaceCount; iFace++)
2447 const CubeFace& cubeFace = faces[iFace];
2448 gContext.mDrawList->AddConvexPolyFilled(cubeFace.faceCoordsScreen, 4, cubeFace.color);
2454 void DrawGrid(
const float* view,
const float* projection,
const float* matrix,
const float gridSize)
2461 for (
float f = -gridSize; f <= gridSize; f += 1.f)
2463 for (
int dir = 0; dir < 2; dir++)
2465 vec_t ptA =
makeVect(dir ? -gridSize : f, 0.f, dir ? f : -gridSize);
2466 vec_t ptB =
makeVect(dir ? gridSize : f, 0.f, dir ? f : gridSize);
2467 bool visible =
true;
2468 for (
int i = 0; i < 6; i++)
2472 if (dA < 0.f && dB < 0.f)
2477 if (dA > 0.f && dB > 0.f)
2483 float len = fabsf(dA - dB);
2484 float t = fabsf(dA) / len;
2489 float len = fabsf(dB - dA);
2490 float t = fabsf(dB) / len;
2496 ImU32 col = IM_COL32(0x80, 0x80, 0x80, 0xFF);
2497 col = (fmodf(fabsf(f), 10.f) < FLT_EPSILON) ? IM_COL32(0x90, 0x90, 0x90, 0xFF) : col;
2498 col = (fabsf(f) < FLT_EPSILON) ? IM_COL32(0x40, 0x40, 0x40, 0xFF): col;
2500 float thickness = 1.f;
2501 thickness = (fmodf(fabsf(f), 10.f) < FLT_EPSILON) ? 1.5f : thickness;
2502 thickness = (fabsf(f) < FLT_EPSILON) ? 2.3f : thickness;
2510 void ViewManipulate(
float* view,
float length, ImVec2 position, ImVec2 size, ImU32 backgroundColor)
2512 static bool isDraging =
false;
2513 static bool isClicking =
false;
2514 static bool isInside =
false;
2515 static vec_t interpolationUp;
2516 static vec_t interpolationDir;
2517 static int interpolationFrames = 0;
2522 svgProjection =
gContext.mProjectionMat;
2524 ImGuiIO& io = ImGui::GetIO();
2525 gContext.mDrawList->AddRectFilled(position, position + size, backgroundColor);
2532 const float distance = 3.f;
2534 float fov = acosf(distance / (sqrtf(distance * distance + 3.f))) *
RAD2DEG;
2535 Perspective(fov / sqrtf(2.f), size.x / size.y, 0.01f, 1000.f, cubeProjection.
m16);
2537 vec_t dir =
makeVect(viewInverse.
m[2][0], viewInverse.
m[2][1], viewInverse.
m[2][2]);
2538 vec_t up =
makeVect(viewInverse.
m[1][0], viewInverse.
m[1][1], viewInverse.
m[1][2]);
2539 vec_t eye = dir * distance;
2545 gContext.mProjectionMat = cubeProjection;
2548 const matrix_t res = cubeView * cubeProjection;
2551 static const ImVec2 panelPosition[9] = { ImVec2(0.75f,0.75f), ImVec2(0.25f, 0.75f), ImVec2(0.f, 0.75f),
2552 ImVec2(0.75f, 0.25f), ImVec2(0.25f, 0.25f), ImVec2(0.f, 0.25f),
2553 ImVec2(0.75f, 0.f), ImVec2(0.25f, 0.f), ImVec2(0.f, 0.f) };
2555 static const ImVec2 panelSize[9] = { ImVec2(0.25f,0.25f), ImVec2(0.5f, 0.25f), ImVec2(0.25f, 0.25f),
2556 ImVec2(0.25f, 0.5f), ImVec2(0.5f, 0.5f), ImVec2(0.25f, 0.5f),
2557 ImVec2(0.25f, 0.25f), ImVec2(0.5f, 0.25f), ImVec2(0.25f, 0.25f) };
2561 for (
int iPass = 0; iPass < 2; iPass++)
2563 for (
int iFace = 0; iFace < 6; iFace++)
2565 const int normalIndex = (iFace % 3);
2566 const int perpXIndex = (normalIndex + 1) % 3;
2567 const int perpYIndex = (normalIndex + 2) % 3;
2568 const float invert = (iFace > 2) ? -1.f : 1.f;
2571 const vec_t boxOrigin =
directionUnary[normalIndex] * -invert - indexVectorX - indexVectorY;
2575 vec_t viewSpaceNormal = n;
2576 vec_t viewSpacePoint = n * 0.5f;
2580 const vec_t viewSpaceFacePlan =
BuildPlan(viewSpacePoint, viewSpaceNormal);
2583 if (viewSpaceFacePlan.
w > 0.f)
2600 for (
int iPanel = 0; iPanel < 9; iPanel++)
2602 vec_t boxCoord = boxOrigin + indexVectorX * float(iPanel % 3) + indexVectorY * float(iPanel / 3) +
makeVect(1.f, 1.f, 1.f);
2603 const ImVec2 p = panelPosition[iPanel] * 2.f;
2604 const ImVec2 s = panelSize[iPanel] * 2.f;
2605 ImVec2 faceCoordsScreen[4];
2606 vec_t panelPos[4] = { dx * p.
x + dy * p.
y,
2607 dx * p.
x + dy * (p.y + s.y),
2608 dx * (p.x + s.x) + dy * (p.y + s.y),
2609 dx * (p.x + s.x) + dy * p.
y };
2611 for (
unsigned int iCoord = 0; iCoord < 4; iCoord++)
2613 faceCoordsScreen[iCoord] =
worldToPos((panelPos[iCoord] + origin) * 0.5f * invert, res, position, size);
2616 const ImVec2 panelCorners[2] = { panelPosition[iPanel], panelPosition[iPanel] + panelSize[iPanel] };
2617 bool insidePanel = localx > panelCorners[0].
x && localx < panelCorners[1].x&& localy > panelCorners[0].y && localy < panelCorners[1].y;
2618 int boxCoordInt = int(boxCoord.
x * 9.f + boxCoord.
y * 3.f + boxCoord.
z);
2619 assert(boxCoordInt < 27);
2620 boxes[boxCoordInt] |= insidePanel && (!isDraging);
2625 gContext.mDrawList->AddConvexPolyFilled(faceCoordsScreen, 4, (
directionColor[normalIndex] | IM_COL32(0x80, 0x80, 0x80, 0x80)) | (isInside ? IM_COL32(0x08, 0x08, 0x08, 0) : 0));
2626 if (boxes[boxCoordInt])
2628 gContext.mDrawList->AddConvexPolyFilled(faceCoordsScreen, 4, IM_COL32(0xF0, 0xA0, 0x60, 0x80));
2630 if (!io.MouseDown[0] && !isDraging && isClicking)
2633 int cx = boxCoordInt / 9;
2634 int cy = (boxCoordInt - cx * 9) / 3;
2635 int cz = boxCoordInt % 3;
2636 interpolationDir =
makeVect(1.f - cx, 1.f - cy, 1.f - cz);
2639 if (fabsf(
Dot(interpolationDir, referenceUp)) > 1.0f - 0.01f)
2642 if (fabsf(right.
x) > fabsf(right.
z))
2651 interpolationUp =
Cross(interpolationDir, right);
2656 interpolationUp = referenceUp;
2658 interpolationFrames = 40;
2661 if (io.MouseDown[0] && !isDraging)
2670 if (interpolationFrames)
2672 interpolationFrames--;
2674 newDir.
Lerp(interpolationDir, 0.2f);
2678 newUp.
Lerp(interpolationUp, 0.3f);
2680 newUp = interpolationUp;
2681 vec_t newEye = camTarget + newDir * length;
2682 LookAt(&newEye.
x, &camTarget.
x, &newUp.
x, view);
2684 isInside = ImRect(position, position + size).Contains(io.MousePos);
2687 if (!isDraging && io.MouseDown[0] && isInside && (fabsf(io.MouseDelta.x) > 0.f || fabsf(io.MouseDelta.y) > 0.f))
2692 else if (isDraging && !io.MouseDown[0])
2714 float dt =
Dot(planDir, newDir);
2717 newDir += planDir * dt;
2721 vec_t newEye = camTarget + newDir * length;
2722 LookAt(&newEye.
x, &camTarget.
x, &referenceUp.
x, view);
void SetGizmoSizeClipSpace(float value)
static const float DEG2RAD
static void ComputeColors(ImU32 *colors, int type, OPERATION operation)
static const char * rotationInfoMask[]
void ComputeFrustumPlanes(vec_t *frustum, const float *clip)
static const ImU32 translationLineColor
void SetRect(float x, float y, float width, float height)
static void DrawTranslationGizmo(OPERATION op, int type)
const float screenRotateSize
static bool IsScaleType(int type)
vec_t Normalized(const vec_t &v)
static void DrawRotationGizmo(OPERATION op, int type)
static bool Intersects(OPERATION lhs, OPERATION rhs)
static bool IsTranslateType(int type)
static void HandleAndDrawLocalBounds(const float *bounds, matrix_t *matrix, const float *snapValues, OPERATION operation)
bool IsWithin(T x, T y, T z)
static float DistanceToPlane(const vec_t &point, const vec_t &plan)
void AllowAxisFlip(bool value)
static void ComputeCameraRay(vec_t &rayOrigin, vec_t &rayDir, ImVec2 position=ImVec2(gContext.mX, gContext.mY), ImVec2 size=ImVec2(gContext.mWidth, gContext.mHeight))
bool Manipulate(const float *view, const float *projection, OPERATION operation, MODE mode, float *matrix, float *deltaMatrix, const float *snap, const float *localBounds, const float *boundsSnap)
static float ComputeAngleOnPlan()
static int GetScaleType(OPERATION op)
static bool IsInContextRect(ImVec2 p)
static bool Contains(OPERATION lhs, OPERATION rhs)
static bool IsRotateType(int type)
void Cross(const float *a, const float *b, float *r)
static const ImU32 directionColor[3]
void SetImGuiContext(ImGuiContext *ctx)
static const vec_t directionUnary[3]
vec_t makeVect(float _x, float _y, float _z=0.f, float _w=0.f)
static float GetSegmentLengthClipSpace(const vec_t &start, const vec_t &end)
void FPU_MatrixF_x_MatrixF(const float *a, const float *b, float *r)
static float GetParallelogram(const vec_t &ptO, const vec_t &ptA, const vec_t &ptB)
static bool HandleScale(float *matrix, float *deltaMatrix, OPERATION op, int &type, const float *snap)
static bool HandleTranslation(float *matrix, float *deltaMatrix, OPERATION op, int &type, const float *snap)
void Perspective(float fovyInDegrees, float aspectRatio, float znear, float zfar, float *m16)
static const char * scaleInfoMask[]
static bool operator==(OPERATION lhs, int rhs)
void SetOrthographic(bool isOrthographic)
static const float quadUV[8]
static bool HandleRotation(float *matrix, float *deltaMatrix, OPERATION op, int &type, const float *snap)
static void ComputeSnap(float *value, float snap)
vec_t BuildPlan(const vec_t &p_point1, const vec_t &p_normal)
static bool CanActivate()
static int GetRotateType(OPERATION op)
static OPERATION operator&(OPERATION lhs, OPERATION rhs)
void DrawCubes(const float *view, const float *projection, const float *matrices, int matrixCount)
static void DrawHatchedAxis(const vec_t &axis)
static bool operator!=(OPERATION lhs, int rhs)
float Dot(const float *a, const float *b)
static const float quadMin
static int GetMoveType(OPERATION op, vec_t *gizmoHitProportion)
static ImVec2 worldToPos(const vec_t &worldPos, const matrix_t &mat, ImVec2 position=ImVec2(gContext.mX, gContext.mY), ImVec2 size=ImVec2(gContext.mWidth, gContext.mHeight))
void DrawGrid(const float *view, const float *projection, const float *matrix, const float gridSize)
static void ComputeTripodAxisAndVisibility(int axisIndex, vec_t &dirAxis, vec_t &dirPlaneX, vec_t &dirPlaneY, bool &belowAxisLimit, bool &belowPlaneLimit)
void DecomposeMatrixToComponents(const float *matrix, float *translation, float *rotation, float *scale)
void RecomposeMatrixFromComponents(const float *translation, const float *rotation, const float *scale, float *matrix)
void SetDrawlist(ImDrawList *drawlist)
static const int halfCircleSegmentCount
void Normalize(const float *a, float *r)
static const float quadMax
static const int translationInfoIndex[]
static void DrawScaleGizmo(OPERATION op, int type)
static const float RAD2DEG
static const ImU32 planeColor[3]
static void ComputeContext(const float *view, const float *projection, float *matrix, MODE mode)
void LookAt(const float *eye, const float *at, const float *up, float *m16)
void Frustum(float left, float right, float bottom, float top, float znear, float zfar, float *m16)
static const ImU32 selectionColor
static const OPERATION TRANSLATE_PLANS[3]
static const char * translationInfoMask[]
static const float snapTension
void ViewManipulate(float *view, float length, ImVec2 position, ImVec2 size, ImU32 backgroundColor)
static const ImU32 inactiveColor
vec_t PointOnSegment(const vec_t &point, const vec_t &vertPos1, const vec_t &vertPos2)
static float IntersectRayPlane(const vec_t &rOrigin, const vec_t &rVector, const vec_t &plan)
ImVec2 mScreenSquareCenter
vec_t mTranslationPlanOrigin
matrix_t mModelSourceInverse
float mRotationAngleOrigin
float mRadiusSquareCenter
float mGizmoSizeClipSpace
vec_t mRotationVectorSource
vec_t mTranslationLastDelta
void Translation(const vec_t &vt)
matrix_t operator*(const matrix_t &mat) const
void Translation(float _x, float _y, float _z)
void Scale(const vec_t &s)
void Multiply(const matrix_t &matrix)
void Multiply(const matrix_t &m1, const matrix_t &m2)
matrix_t(const matrix_t &other)
float GetDeterminant() const
float Inverse(const matrix_t &srcMatrix, bool affine=false)
matrix_t & operator*=(const matrix_t &mat)
void Scale(float _x, float _y, float _z)
void RotationAxis(const vec_t &axis, float angle)
struct ImGuizmo::matrix_t::@361143343175260347357032320102377242354047307227::@301362307350360221377203214104274101264331001140 v
void Cross(const vec_t &v)
vec_t & operator*=(const vec_t &v)
void Set(float _x, float _y, float _z=0.f, float _w=0.f)
void Lerp(const vec_t &v, float t)
vec_t Normalize(const vec_t &v)
float Dot(const vec_t &v) const
const vec_t & operator+() const
vec_t & operator+=(const vec_t &v)
void TransformPoint(const vec_t &v, const matrix_t &matrix)
vec_t & operator-=(const vec_t &v)
bool operator!=(const vec_t &other) const
void TransformPoint(const matrix_t &matrix)
float & operator[](size_t index)
void TransformVector(const vec_t &v, const matrix_t &matrix)
void Transform(const matrix_t &matrix)
void Cross(const vec_t &v1, const vec_t &v2)
vec_t operator*(float f) const
float Dot3(const vec_t &v) const
void TransformVector(const matrix_t &matrix)