|
|
@@ -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);
|