mirror of https://github.com/bkaradzic/bgfx
Updated ImGuizmo.
This commit is contained in:
parent
b906f3445c
commit
3ce80020ec
|
@ -1,5 +1,5 @@
|
|||
// https://github.com/CedricGuillemet/ImGuizmo
|
||||
// v 1.03 WIP
|
||||
// v 1.04 WIP
|
||||
//
|
||||
// The MIT License(MIT)
|
||||
//
|
||||
|
@ -25,6 +25,7 @@
|
|||
//
|
||||
// -------------------------------------------------------------------------------------------
|
||||
// History :
|
||||
// 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.
|
||||
// 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.
|
||||
|
@ -40,43 +41,65 @@
|
|||
//
|
||||
// -------------------------------------------------------------------------------------------
|
||||
// Example
|
||||
//
|
||||
// static ImGuizmo::OPERATION mCurrentGizmoOperation(ImGuizmo::TRANSLATE);
|
||||
// static ImGuizmo::MODE mCurrentGizmoMode(ImGuizmo::LOCAL);
|
||||
//
|
||||
// // Maya shortcut keys
|
||||
// if (ImGui::IsKeyPressed(90)) // w Key
|
||||
// mCurrentGizmoOperation = ImGuizmo::TRANSLATE;
|
||||
// if (ImGui::IsKeyPressed(69)) // e Key
|
||||
// mCurrentGizmoOperation = ImGuizmo::ROTATE;
|
||||
// if (ImGui::IsKeyPressed(82)) // r Key
|
||||
// mCurrentGizmoOperation = ImGuizmo::SCALE;
|
||||
//
|
||||
// if (ImGui::RadioButton("Translate", mCurrentGizmoOperation == ImGuizmo::TRANSLATE))
|
||||
// mCurrentGizmoOperation = ImGuizmo::TRANSLATE;
|
||||
// ImGui::SameLine();
|
||||
// if (ImGui::RadioButton("Rotate", mCurrentGizmoOperation == ImGuizmo::ROTATE))
|
||||
// mCurrentGizmoOperation = ImGuizmo::ROTATE;
|
||||
// ImGui::SameLine();
|
||||
// if (ImGui::RadioButton("Scale", mCurrentGizmoOperation == ImGuizmo::SCALE))
|
||||
// mCurrentGizmoOperation = ImGuizmo::SCALE;
|
||||
//
|
||||
// float matrixTranslation[3], matrixRotation[3], matrixScale[3];
|
||||
// ImGuizmo::DecomposeMatrixToComponents(gizmoMatrix.m16, matrixTranslation, matrixRotation, matrixScale);
|
||||
// ImGui::InputFloat3("Tr", matrixTranslation, 3);
|
||||
// ImGui::InputFloat3("Rt", matrixRotation, 3);
|
||||
// ImGui::InputFloat3("Sc", matrixScale, 3);
|
||||
// ImGuizmo::RecomposeMatrixFromComponents(matrixTranslation, matrixRotation, matrixScale, gizmoMatrix.m16);
|
||||
//
|
||||
// if (ImGui::RadioButton("Local", mCurrentGizmoMode == ImGuizmo::LOCAL))
|
||||
// mCurrentGizmoMode = ImGuizmo::LOCAL;
|
||||
// ImGui::SameLine();
|
||||
// if (ImGui::RadioButton("World", mCurrentGizmoMode == ImGuizmo::WORLD))
|
||||
// mCurrentGizmoMode = ImGuizmo::WORLD;
|
||||
//
|
||||
// ImGuizmo::Manipulate(gCurrentCamera->mView.m16, gCurrentCamera->mProjection.m16, mCurrentGizmoOperation, mCurrentGizmoMode, gizmoMatrix.m16);
|
||||
//
|
||||
#if 0
|
||||
void EditTransform(const Camera& camera, matrix_t& matrix)
|
||||
{
|
||||
static ImGuizmo::OPERATION mCurrentGizmoOperation(ImGuizmo::ROTATE);
|
||||
static ImGuizmo::MODE mCurrentGizmoMode(ImGuizmo::WORLD);
|
||||
if (ImGui::IsKeyPressed(90))
|
||||
mCurrentGizmoOperation = ImGuizmo::TRANSLATE;
|
||||
if (ImGui::IsKeyPressed(69))
|
||||
mCurrentGizmoOperation = ImGuizmo::ROTATE;
|
||||
if (ImGui::IsKeyPressed(82)) // r Key
|
||||
mCurrentGizmoOperation = ImGuizmo::SCALE;
|
||||
if (ImGui::RadioButton("Translate", mCurrentGizmoOperation == ImGuizmo::TRANSLATE))
|
||||
mCurrentGizmoOperation = ImGuizmo::TRANSLATE;
|
||||
ImGui::SameLine();
|
||||
if (ImGui::RadioButton("Rotate", mCurrentGizmoOperation == ImGuizmo::ROTATE))
|
||||
mCurrentGizmoOperation = ImGuizmo::ROTATE;
|
||||
ImGui::SameLine();
|
||||
if (ImGui::RadioButton("Scale", mCurrentGizmoOperation == ImGuizmo::SCALE))
|
||||
mCurrentGizmoOperation = ImGuizmo::SCALE;
|
||||
float matrixTranslation[3], matrixRotation[3], matrixScale[3];
|
||||
ImGuizmo::DecomposeMatrixToComponents(matrix.m16, matrixTranslation, matrixRotation, matrixScale);
|
||||
ImGui::InputFloat3("Tr", matrixTranslation, 3);
|
||||
ImGui::InputFloat3("Rt", matrixRotation, 3);
|
||||
ImGui::InputFloat3("Sc", matrixScale, 3);
|
||||
ImGuizmo::RecomposeMatrixFromComponents(matrixTranslation, matrixRotation, matrixScale, matrix.m16);
|
||||
|
||||
if (mCurrentGizmoOperation != ImGuizmo::SCALE)
|
||||
{
|
||||
if (ImGui::RadioButton("Local", mCurrentGizmoMode == ImGuizmo::LOCAL))
|
||||
mCurrentGizmoMode = ImGuizmo::LOCAL;
|
||||
ImGui::SameLine();
|
||||
if (ImGui::RadioButton("World", mCurrentGizmoMode == ImGuizmo::WORLD))
|
||||
mCurrentGizmoMode = ImGuizmo::WORLD;
|
||||
}
|
||||
static bool useSnap(false);
|
||||
if (ImGui::IsKeyPressed(83))
|
||||
useSnap = !useSnap;
|
||||
ImGui::Checkbox("", &useSnap);
|
||||
ImGui::SameLine();
|
||||
vec_t snap;
|
||||
switch (mCurrentGizmoOperation)
|
||||
{
|
||||
case ImGuizmo::TRANSLATE:
|
||||
snap = config.mSnapTranslation;
|
||||
ImGui::InputFloat3("Snap", &snap.x);
|
||||
break;
|
||||
case ImGuizmo::ROTATE:
|
||||
snap = config.mSnapRotation;
|
||||
ImGui::InputFloat("Angle Snap", &snap.x);
|
||||
break;
|
||||
case ImGuizmo::SCALE:
|
||||
snap = config.mSnapScale;
|
||||
ImGui::InputFloat("Scale Snap", &snap.x);
|
||||
break;
|
||||
}
|
||||
|
||||
ImGuizmo::Manipulate(camera.mView.m16, camera.mProjection.m16, mCurrentGizmoOperation, mCurrentGizmoMode, matrix.m16, NULL, useSnap ? &snap.x : NULL);
|
||||
}
|
||||
#endif
|
||||
#pragma once
|
||||
|
||||
namespace ImGuizmo
|
||||
|
|
|
@ -491,11 +491,13 @@ namespace ImGuizmo
|
|||
|
||||
ImDrawList* mDrawList;
|
||||
|
||||
MODE mMode;
|
||||
matrix_t mViewMat;
|
||||
matrix_t mProjectionMat;
|
||||
matrix_t mModel;
|
||||
matrix_t mModelInverse;
|
||||
matrix_t mModelSource;
|
||||
matrix_t mModelSourceInverse;
|
||||
matrix_t mMVP;
|
||||
matrix_t mViewProjection;
|
||||
|
||||
|
@ -526,6 +528,7 @@ namespace ImGuizmo
|
|||
vec_t mRotationVectorSource;
|
||||
float mRotationAngle;
|
||||
float mRotationAngleOrigin;
|
||||
//vec_t mWorldToLocalAxis;
|
||||
|
||||
// scale
|
||||
vec_t mScale;
|
||||
|
@ -646,6 +649,7 @@ namespace ImGuizmo
|
|||
|
||||
static void ComputeContext(const float *view, const float *projection, float *matrix, MODE mode)
|
||||
{
|
||||
gContext.mMode = mode;
|
||||
gContext.mViewMat = *(matrix_t*)view;
|
||||
gContext.mProjectionMat = *(matrix_t*)projection;
|
||||
|
||||
|
@ -662,6 +666,7 @@ namespace ImGuizmo
|
|||
gContext.mModelScaleOrigin.Set(gContext.mModelSource.v.right.Length(), gContext.mModelSource.v.up.Length(), gContext.mModelSource.v.dir.Length());
|
||||
|
||||
gContext.mModelInverse.Inverse(gContext.mModel);
|
||||
gContext.mModelSourceInverse.Inverse(gContext.mModelSource);
|
||||
gContext.mViewProjection = gContext.mViewMat * gContext.mProjectionMat;
|
||||
gContext.mMVP = gContext.mModel * gContext.mViewProjection;
|
||||
|
||||
|
@ -1101,6 +1106,7 @@ namespace ImGuizmo
|
|||
static void HandleTranslation(float *matrix, float *deltaMatrix, int& type, float *snap)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
bool applyRotationLocaly = gContext.mMode == LOCAL || type == MOVE_SCREEN;
|
||||
|
||||
// move
|
||||
if (gContext.mbUsing)
|
||||
|
@ -1125,8 +1131,18 @@ namespace ImGuizmo
|
|||
if (snap)
|
||||
{
|
||||
vec_t cumulativeDelta = gContext.mModel.v.position + delta - gContext.mMatrixOrigin;
|
||||
ComputeSnap(cumulativeDelta, snap);
|
||||
if (applyRotationLocaly)
|
||||
{
|
||||
cumulativeDelta.TransformVector(gContext.mModelSourceInverse);
|
||||
ComputeSnap(cumulativeDelta, snap);
|
||||
cumulativeDelta.TransformVector(gContext.mModelSource);
|
||||
}
|
||||
else
|
||||
{
|
||||
ComputeSnap(cumulativeDelta, snap);
|
||||
}
|
||||
delta = gContext.mMatrixOrigin + cumulativeDelta - gContext.mModel.v.position;
|
||||
|
||||
}
|
||||
|
||||
// compute matrix & delta
|
||||
|
@ -1134,6 +1150,8 @@ namespace ImGuizmo
|
|||
deltaMatrixTranslation.Translation(delta);
|
||||
if (deltaMatrix)
|
||||
memcpy(deltaMatrix, deltaMatrixTranslation.m16, sizeof(float) * 16);
|
||||
|
||||
|
||||
matrix_t res = gContext.mModelSource * deltaMatrixTranslation;
|
||||
*(matrix_t*)matrix = res;
|
||||
|
||||
|
@ -1230,11 +1248,15 @@ namespace ImGuizmo
|
|||
matrix_t deltaMatrixScale;
|
||||
deltaMatrixScale.Scale(gContext.mScale * gContext.mScaleValueOrigin);
|
||||
|
||||
if (deltaMatrix)
|
||||
memcpy(deltaMatrix, deltaMatrixScale.m16, sizeof(float) * 16);
|
||||
matrix_t res = deltaMatrixScale * gContext.mModel;
|
||||
*(matrix_t*)matrix = res;
|
||||
|
||||
if (deltaMatrix)
|
||||
{
|
||||
deltaMatrixScale.Scale(gContext.mScale);
|
||||
memcpy(deltaMatrix, deltaMatrixScale.m16, sizeof(float) * 16);
|
||||
}
|
||||
|
||||
if (!io.MouseDown[0])
|
||||
gContext.mbUsing = false;
|
||||
|
||||
|
@ -1245,6 +1267,7 @@ namespace ImGuizmo
|
|||
static void HandleRotation(float *matrix, float *deltaMatrix, int& type, float *snap)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
bool applyRotationLocaly = gContext.mMode == LOCAL || type == ROTATE_SCREEN;
|
||||
|
||||
if (!gContext.mbUsing)
|
||||
{
|
||||
|
@ -1255,7 +1278,14 @@ namespace ImGuizmo
|
|||
gContext.mCurrentOperation = type;
|
||||
const vec_t rotatePlanNormal[] = { gContext.mModel.v.right, gContext.mModel.v.up, gContext.mModel.v.dir, -gContext.mCameraDir };
|
||||
// pickup plan
|
||||
gContext.mTranslationPlan = BuildPlan(gContext.mModel.v.position, rotatePlanNormal[type - ROTATE_X]);
|
||||
if (applyRotationLocaly)
|
||||
{
|
||||
gContext.mTranslationPlan = BuildPlan(gContext.mModel.v.position, rotatePlanNormal[type - ROTATE_X]);
|
||||
}
|
||||
else
|
||||
{
|
||||
gContext.mTranslationPlan = BuildPlan(gContext.mModelSource.v.position, directionUnary[type - ROTATE_X]);
|
||||
}
|
||||
|
||||
const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan);
|
||||
vec_t localPos = gContext.mRayOrigin + gContext.mRayVector * len - gContext.mModel.v.position;
|
||||
|
@ -1274,7 +1304,9 @@ namespace ImGuizmo
|
|||
ComputeSnap(&gContext.mRotationAngle, &snapInRadian);
|
||||
}
|
||||
vec_t rotationAxisLocalSpace;
|
||||
|
||||
rotationAxisLocalSpace.TransformVector(makeVect(gContext.mTranslationPlan.x, gContext.mTranslationPlan.y, gContext.mTranslationPlan.z, 0.f), gContext.mModelInverse);
|
||||
rotationAxisLocalSpace.Normalize();
|
||||
|
||||
matrix_t deltaRotation;
|
||||
deltaRotation.RotationAxis(rotationAxisLocalSpace, gContext.mRotationAngle - gContext.mRotationAngleOrigin);
|
||||
|
@ -1283,8 +1315,18 @@ namespace ImGuizmo
|
|||
matrix_t scaleOrigin;
|
||||
scaleOrigin.Scale(gContext.mModelScaleOrigin);
|
||||
|
||||
if (applyRotationLocaly)
|
||||
{
|
||||
*(matrix_t*)matrix = scaleOrigin * deltaRotation * gContext.mModel;
|
||||
}
|
||||
else
|
||||
{
|
||||
matrix_t res = gContext.mModelSource;
|
||||
res.v.position.Set(0.f);
|
||||
|
||||
*(matrix_t*)matrix = scaleOrigin * deltaRotation * gContext.mModel;
|
||||
*(matrix_t*)matrix = res * deltaRotation;
|
||||
((matrix_t*)matrix)->v.position = gContext.mModelSource.v.position;
|
||||
}
|
||||
|
||||
if (deltaMatrix)
|
||||
{
|
||||
|
@ -1348,6 +1390,13 @@ namespace ImGuizmo
|
|||
// set delta to identity
|
||||
if (deltaMatrix)
|
||||
((matrix_t*)deltaMatrix)->SetToIdentity();
|
||||
|
||||
// behind camera
|
||||
vec_t camSpacePosition;
|
||||
camSpacePosition.TransformPoint(makeVect(0.f, 0.f, 0.f), gContext.mMVP);
|
||||
if (camSpacePosition.z < 0.001f)
|
||||
return;
|
||||
|
||||
// --
|
||||
int type = NONE;
|
||||
if (gContext.mbEnable)
|
||||
|
@ -1399,6 +1448,23 @@ namespace ImGuizmo
|
|||
directionUnary[normalIndex] - directionUnary[perpXIndex] - directionUnary[perpYIndex],
|
||||
directionUnary[normalIndex] - directionUnary[perpXIndex] + directionUnary[perpYIndex],
|
||||
};
|
||||
|
||||
// clipping
|
||||
bool skipFace = false;
|
||||
for (unsigned int iCoord = 0; iCoord < 4; iCoord++)
|
||||
{
|
||||
vec_t camSpacePosition;
|
||||
camSpacePosition.TransformPoint(faceCoords[iCoord] * 0.5f * invert, gContext.mMVP);
|
||||
if (camSpacePosition.z < 0.001f)
|
||||
{
|
||||
skipFace = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (skipFace)
|
||||
continue;
|
||||
|
||||
// 3D->2D
|
||||
ImVec2 faceCoordsScreen[4];
|
||||
for (unsigned int iCoord = 0; iCoord < 4; iCoord++)
|
||||
faceCoordsScreen[iCoord] = worldToPos(faceCoords[iCoord] * 0.5f * invert, res);
|
||||
|
|
Loading…
Reference in New Issue