mirror of
https://github.com/bkaradzic/bgfx.git
synced 2026-02-21 06:13:07 +01:00
Updated ImGuizmo.
This commit is contained in:
11
3rdparty/ocornut-imgui/widgets/gizmo.h
vendored
11
3rdparty/ocornut-imgui/widgets/gizmo.h
vendored
@@ -1,5 +1,5 @@
|
||||
// https://github.com/CedricGuillemet/ImGuizmo
|
||||
// v 1.02 WIP
|
||||
// v 1.03 WIP
|
||||
//
|
||||
// The MIT License(MIT)
|
||||
//
|
||||
@@ -25,17 +25,18 @@
|
||||
//
|
||||
// -------------------------------------------------------------------------------------------
|
||||
// History :
|
||||
// 2016/09/09 Hatched negative axis. Snapping. Documentation update.
|
||||
// 2016/09/04 Axis switch and translation plan autohiding. Scale transform stability improved
|
||||
// 2016/09/01 Mogwai changed to Manipulate. Draw debug cube. Fixed inverted scale. Mixing scale and translation/rotation gives bad results.
|
||||
// 2016/08/31 First version
|
||||
//
|
||||
// -------------------------------------------------------------------------------------------
|
||||
// Future:
|
||||
// Future (no order):
|
||||
//
|
||||
// - Multi view
|
||||
// - display rotation/translation/scale infos in local/world space and not only local
|
||||
// - finish local/world matrix application
|
||||
// - snap
|
||||
// - OPERATION as bitmask
|
||||
//
|
||||
// -------------------------------------------------------------------------------------------
|
||||
// Example
|
||||
@@ -73,7 +74,7 @@
|
||||
// if (ImGui::RadioButton("World", mCurrentGizmoMode == ImGuizmo::WORLD))
|
||||
// mCurrentGizmoMode = ImGuizmo::WORLD;
|
||||
//
|
||||
// ImGuizmo::Mogwai(gCurrentCamera->mView.m16, gCurrentCamera->mProjection.m16, mCurrentGizmoOperation, mCurrentGizmoMode, gizmoMatrix.m16);
|
||||
// ImGuizmo::Manipulate(gCurrentCamera->mView.m16, gCurrentCamera->mProjection.m16, mCurrentGizmoOperation, mCurrentGizmoMode, gizmoMatrix.m16);
|
||||
//
|
||||
|
||||
#pragma once
|
||||
@@ -128,5 +129,5 @@ namespace ImGuizmo
|
||||
WORLD
|
||||
};
|
||||
|
||||
void Manipulate(const float *view, const float *projection, OPERATION operation, MODE mode, float *matrix, float *deltaMatrix = 0);
|
||||
void Manipulate(const float *view, const float *projection, OPERATION operation, MODE mode, float *matrix, float *deltaMatrix = 0, float *snap = 0);
|
||||
};
|
||||
|
||||
120
3rdparty/ocornut-imgui/widgets/gizmo.inl
vendored
120
3rdparty/ocornut-imgui/widgets/gizmo.inl
vendored
@@ -530,6 +530,7 @@ namespace ImGuizmo
|
||||
// scale
|
||||
vec_t mScale;
|
||||
vec_t mScaleValueOrigin;
|
||||
float mSaveMousePosx;
|
||||
|
||||
// save axis factor when using gizmo
|
||||
bool mBelowAxisLimit[3];
|
||||
@@ -550,7 +551,7 @@ namespace ImGuizmo
|
||||
static const ImU32 selectionColor = 0xFF1080FF;
|
||||
static const ImU32 inactiveColor = 0x99999999;
|
||||
static const ImU32 translationLineColor = 0xAAAAAAAA;
|
||||
static const char *translationInfoMask[] = { "X : %5.2f", "Y : %5.2f", "Z : %5.2f", "X : %5.2f Y : %5.2f", "Y : %5.2f Z : %5.2f", "X : %5.2f Z : %5.2f", "X : %5.2f Y : %5.2f Z : %5.2f" };
|
||||
static const char *translationInfoMask[] = { "X : %5.3f", "Y : %5.3f", "Z : %5.3f", "X : %5.3f Y : %5.3f", "Y : %5.3f Z : %5.3f", "X : %5.3f Z : %5.3f", "X : %5.3f Y : %5.3f Z : %5.3f" };
|
||||
static const char *scaleInfoMask[] = { "X : %5.2f", "Y : %5.2f", "Z : %5.2f", "XYZ : %5.2f" };
|
||||
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" };
|
||||
static const int translationInfoIndex[] = { 0,0,0, 1,0,0, 2,0,0, 0,1,0, 0,2,0, 1,2,0, 0,1,2 };
|
||||
@@ -558,6 +559,7 @@ namespace ImGuizmo
|
||||
static const float quadMax = 0.8f;
|
||||
static const float quadUV[8] = { quadMin, quadMin, quadMin, quadMax, quadMax, quadMax, quadMax, quadMin };
|
||||
static const int halfCircleSegmentCount = 64;
|
||||
static const float snapTension = 0.5f;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -763,6 +765,39 @@ namespace ImGuizmo
|
||||
}
|
||||
}
|
||||
|
||||
static void ComputeSnap(float*value, float *snap)
|
||||
{
|
||||
if (*snap <= FLT_EPSILON)
|
||||
return;
|
||||
float modulo = fmodf(*value, *snap);
|
||||
float moduloRatio = fabsf(modulo) / *snap;
|
||||
if (moduloRatio < snapTension)
|
||||
*value -= modulo;
|
||||
else if (moduloRatio >(1.f - snapTension))
|
||||
*value = *value - modulo + *snap * ((*value<0.f) ? -1.f : 1.f);
|
||||
}
|
||||
static void ComputeSnap(vec_t& value, float *snap)
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
ComputeSnap(&value[i], &snap[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static float ComputeAngleOnPlan()
|
||||
{
|
||||
const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan);
|
||||
vec_t localPos = Normalized(gContext.mRayOrigin + gContext.mRayVector * len - gContext.mModel.v.position);
|
||||
|
||||
vec_t perpendicularVector;
|
||||
perpendicularVector.Cross(gContext.mRotationVectorSource, gContext.mTranslationPlan);
|
||||
perpendicularVector.Normalize();
|
||||
float acosAngle = Clamp(Dot(localPos, gContext.mRotationVectorSource), -0.9999f, 0.9999f);
|
||||
float angle = acosf(acosAngle);
|
||||
angle *= (Dot(localPos, perpendicularVector) < 0.f) ? 1.f : -1.f;
|
||||
return angle;
|
||||
}
|
||||
|
||||
static void DrawRotationGizmo(int type)
|
||||
{
|
||||
ImDrawList* drawList = gContext.mDrawList;
|
||||
@@ -818,6 +853,16 @@ namespace ImGuizmo
|
||||
}
|
||||
}
|
||||
|
||||
static void DrawHatchedAxis(const vec_t& axis)
|
||||
{
|
||||
for (int j = 1; j < 10; j++)
|
||||
{
|
||||
ImVec2 baseSSpace2 = worldToPos(axis * 0.05f * (float)(j * 2) * gContext.mScreenFactor, gContext.mMVP);
|
||||
ImVec2 worldDirSSpace2 = worldToPos(axis * 0.05f * (float)(j * 2 + 1) * gContext.mScreenFactor, gContext.mMVP);
|
||||
gContext.mDrawList->AddLine(baseSSpace2, worldDirSSpace2, 0x80000000, 6.f);
|
||||
}
|
||||
}
|
||||
|
||||
static void DrawScaleGizmo(int type)
|
||||
{
|
||||
ImDrawList* drawList = gContext.mDrawList;
|
||||
@@ -853,9 +898,12 @@ namespace ImGuizmo
|
||||
drawList->AddLine(baseSSpace, worldDirSSpaceNoScale, 0xFF404040, 6.f);
|
||||
drawList->AddCircleFilled(worldDirSSpaceNoScale, 10.f, 0xFF404040);
|
||||
}
|
||||
|
||||
|
||||
drawList->AddLine(baseSSpace, worldDirSSpace, colors[i + 1], 6.f);
|
||||
drawList->AddCircleFilled(worldDirSSpace, 10.f, colors[i + 1]);
|
||||
|
||||
if (gContext.mAxisFactor[i] < 0.f)
|
||||
DrawHatchedAxis(dirPlaneX * scaleDisplay[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -877,9 +925,9 @@ namespace ImGuizmo
|
||||
drawList->AddText(ImVec2(destinationPosOnScreen.x + 15, destinationPosOnScreen.y + 15), 0xFF000000, tmps);
|
||||
drawList->AddText(ImVec2(destinationPosOnScreen.x + 14, destinationPosOnScreen.y + 14), 0xFFFFFFFF, tmps);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void DrawTranslationGizmo(int type)
|
||||
{
|
||||
ImDrawList* drawList = gContext.mDrawList;
|
||||
@@ -905,6 +953,9 @@ namespace ImGuizmo
|
||||
ImVec2 worldDirSSpace = worldToPos(dirPlaneX * gContext.mScreenFactor, gContext.mMVP);
|
||||
|
||||
drawList->AddLine(baseSSpace, worldDirSSpace, colors[i + 1], 6.f);
|
||||
|
||||
if (gContext.mAxisFactor[i] < 0.f)
|
||||
DrawHatchedAxis(dirPlaneX);
|
||||
}
|
||||
|
||||
// draw plane
|
||||
@@ -1047,7 +1098,7 @@ namespace ImGuizmo
|
||||
return type;
|
||||
}
|
||||
|
||||
static void HandleTranslation(float *matrix, float *deltaMatrix, int& type)
|
||||
static void HandleTranslation(float *matrix, float *deltaMatrix, int& type, float *snap)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
@@ -1056,9 +1107,11 @@ namespace ImGuizmo
|
||||
{
|
||||
const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan);
|
||||
vec_t newPos = gContext.mRayOrigin + gContext.mRayVector * len;
|
||||
|
||||
// compute delta
|
||||
vec_t newOrigin = newPos - gContext.mRelativeOrigin * gContext.mScreenFactor;
|
||||
vec_t delta = newOrigin - gContext.mModel.v.position;
|
||||
|
||||
|
||||
// 1 axis constraint
|
||||
if (gContext.mCurrentOperation >= MOVE_X && gContext.mCurrentOperation <= MOVE_Z)
|
||||
{
|
||||
@@ -1068,8 +1121,15 @@ namespace ImGuizmo
|
||||
delta = axisValue * lengthOnAxis;
|
||||
}
|
||||
|
||||
// snap
|
||||
if (snap)
|
||||
{
|
||||
vec_t cumulativeDelta = gContext.mModel.v.position + delta - gContext.mMatrixOrigin;
|
||||
ComputeSnap(cumulativeDelta, snap);
|
||||
delta = gContext.mMatrixOrigin + cumulativeDelta - gContext.mModel.v.position;
|
||||
}
|
||||
|
||||
// compute matrix & delta
|
||||
gContext.mTranslationPlanOrigin += delta;
|
||||
matrix_t deltaMatrixTranslation;
|
||||
deltaMatrixTranslation.Translation(delta);
|
||||
if (deltaMatrix)
|
||||
@@ -1103,7 +1163,7 @@ namespace ImGuizmo
|
||||
}
|
||||
}
|
||||
|
||||
static void HandleScale(float *matrix, float *deltaMatrix, int& type)
|
||||
static void HandleScale(float *matrix, float *deltaMatrix, int& type, float *snap)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
@@ -1125,6 +1185,7 @@ namespace ImGuizmo
|
||||
gContext.mScale.Set(1.f, 1.f, 1.f);
|
||||
gContext.mRelativeOrigin = (gContext.mTranslationPlanOrigin - gContext.mModel.v.position) * (1.f / gContext.mScreenFactor);
|
||||
gContext.mScaleValueOrigin = makeVect(gContext.mModelSource.v.right.Length(), gContext.mModelSource.v.up.Length(), gContext.mModelSource.v.dir.Length());
|
||||
gContext.mSaveMousePosx = io.MousePos.x;
|
||||
}
|
||||
}
|
||||
// scale
|
||||
@@ -1150,10 +1211,21 @@ namespace ImGuizmo
|
||||
}
|
||||
else
|
||||
{
|
||||
float scaleDelta = io.MouseDelta.x * 0.01f;
|
||||
float scaleDelta = (io.MousePos.x - gContext.mSaveMousePosx) * 0.01f;
|
||||
gContext.mScale.Set(max(1.f + scaleDelta, 0.001f));
|
||||
}
|
||||
|
||||
// snap
|
||||
if (snap)
|
||||
{
|
||||
float scaleSnap[] = { snap[0], snap[0], snap[0] };
|
||||
ComputeSnap(gContext.mScale, scaleSnap);
|
||||
}
|
||||
|
||||
// no 0 allowed
|
||||
for (int i = 0; i < 3;i++)
|
||||
gContext.mScale[i] = max(gContext.mScale[i], 0.001f);
|
||||
|
||||
// compute matrix & delta
|
||||
matrix_t deltaMatrixScale;
|
||||
deltaMatrixScale.Scale(gContext.mScale * gContext.mScaleValueOrigin);
|
||||
@@ -1170,21 +1242,7 @@ namespace ImGuizmo
|
||||
}
|
||||
}
|
||||
|
||||
static float ComputeAngleOnPlan()
|
||||
{
|
||||
const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan);
|
||||
vec_t localPos = Normalized(gContext.mRayOrigin + gContext.mRayVector * len - gContext.mModel.v.position);
|
||||
|
||||
vec_t perpendicularVector;
|
||||
perpendicularVector.Cross(gContext.mRotationVectorSource, gContext.mTranslationPlan);
|
||||
perpendicularVector.Normalize();
|
||||
float acosAngle = Clamp(Dot(localPos, gContext.mRotationVectorSource), -0.9999f, 0.9999f);
|
||||
float angle = acosf(acosAngle);
|
||||
angle *= (Dot(localPos, perpendicularVector) < 0.f) ? 1.f : -1.f;
|
||||
return angle;
|
||||
}
|
||||
|
||||
static void HandleRotation(float *matrix, float *deltaMatrix, int& type)
|
||||
static void HandleRotation(float *matrix, float *deltaMatrix, int& type, float *snap)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
@@ -1210,7 +1268,11 @@ namespace ImGuizmo
|
||||
if (gContext.mbUsing)
|
||||
{
|
||||
gContext.mRotationAngle = ComputeAngleOnPlan();
|
||||
|
||||
if (snap)
|
||||
{
|
||||
float snapInRadian = snap[0] * DEG2RAD;
|
||||
ComputeSnap(&gContext.mRotationAngle, &snapInRadian);
|
||||
}
|
||||
vec_t rotationAxisLocalSpace;
|
||||
rotationAxisLocalSpace.TransformVector(makeVect(gContext.mTranslationPlan.x, gContext.mTranslationPlan.y, gContext.mTranslationPlan.z, 0.f), gContext.mModelInverse);
|
||||
|
||||
@@ -1268,7 +1330,7 @@ namespace ImGuizmo
|
||||
float validScale[3];
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (fabsf(scale[i]) < FLT_EPSILON)
|
||||
if (fabsf(scale[i] < FLT_EPSILON))
|
||||
validScale[i] = 0.001f;
|
||||
else
|
||||
validScale[i] = scale[i];
|
||||
@@ -1279,7 +1341,7 @@ namespace ImGuizmo
|
||||
mat.v.position.Set(translation[0], translation[1], translation[2], 1.f);
|
||||
}
|
||||
|
||||
void Manipulate(const float *view, const float *projection, OPERATION operation, MODE mode, float *matrix, float *deltaMatrix)
|
||||
void Manipulate(const float *view, const float *projection, OPERATION operation, MODE mode, float *matrix, float *deltaMatrix, float *snap)
|
||||
{
|
||||
ComputeContext(view, projection, matrix, mode);
|
||||
|
||||
@@ -1293,13 +1355,13 @@ namespace ImGuizmo
|
||||
switch (operation)
|
||||
{
|
||||
case ROTATE:
|
||||
HandleRotation(matrix, deltaMatrix, type);
|
||||
HandleRotation(matrix, deltaMatrix, type, snap);
|
||||
break;
|
||||
case TRANSLATE:
|
||||
HandleTranslation(matrix, deltaMatrix, type);
|
||||
HandleTranslation(matrix, deltaMatrix, type, snap);
|
||||
break;
|
||||
case SCALE:
|
||||
HandleScale(matrix, deltaMatrix, type);
|
||||
HandleScale(matrix, deltaMatrix, type, snap);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user