Ver Fonte

Updated ImGuizmo.

Branimir Karadžić há 9 anos atrás
pai
commit
3ce80020ec

+ 60 - 37
3rdparty/ocornut-imgui/widgets/gizmo.h

@@ -1,5 +1,5 @@
 // https://github.com/CedricGuillemet/ImGuizmo
 // https://github.com/CedricGuillemet/ImGuizmo
-// v 1.03 WIP
+// v 1.04 WIP
 //
 //
 // The MIT License(MIT)
 // The MIT License(MIT)
 // 
 // 
@@ -25,6 +25,7 @@
 //
 //
 // -------------------------------------------------------------------------------------------
 // -------------------------------------------------------------------------------------------
 // History : 
 // 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/09 Hatched negative axis. Snapping. Documentation update.
 // 2016/09/04 Axis switch and translation plan autohiding. Scale transform stability improved
 // 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/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 
 // 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
 #pragma once
 
 
 namespace ImGuizmo
 namespace ImGuizmo

+ 71 - 5
3rdparty/ocornut-imgui/widgets/gizmo.inl

@@ -491,11 +491,13 @@ namespace ImGuizmo
 
 
 		ImDrawList* mDrawList;
 		ImDrawList* mDrawList;
 
 
+		MODE mMode;
 		matrix_t mViewMat;
 		matrix_t mViewMat;
 		matrix_t mProjectionMat;
 		matrix_t mProjectionMat;
 		matrix_t mModel;
 		matrix_t mModel;
 		matrix_t mModelInverse;
 		matrix_t mModelInverse;
 		matrix_t mModelSource;
 		matrix_t mModelSource;
+		matrix_t mModelSourceInverse;
 		matrix_t mMVP;
 		matrix_t mMVP;
 		matrix_t mViewProjection;
 		matrix_t mViewProjection;
 
 
@@ -526,6 +528,7 @@ namespace ImGuizmo
 		vec_t mRotationVectorSource;
 		vec_t mRotationVectorSource;
 		float mRotationAngle;
 		float mRotationAngle;
 		float mRotationAngleOrigin;
 		float mRotationAngleOrigin;
+		//vec_t mWorldToLocalAxis;
 
 
 		// scale
 		// scale
 		vec_t mScale;
 		vec_t mScale;
@@ -646,6 +649,7 @@ namespace ImGuizmo
 
 
 	static void ComputeContext(const float *view, const float *projection, float *matrix, MODE mode)
 	static void ComputeContext(const float *view, const float *projection, float *matrix, MODE mode)
 	{
 	{
+		gContext.mMode = mode;
 		gContext.mViewMat = *(matrix_t*)view;
 		gContext.mViewMat = *(matrix_t*)view;
 		gContext.mProjectionMat = *(matrix_t*)projection;
 		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.mModelScaleOrigin.Set(gContext.mModelSource.v.right.Length(), gContext.mModelSource.v.up.Length(), gContext.mModelSource.v.dir.Length());
 
 
 		gContext.mModelInverse.Inverse(gContext.mModel);
 		gContext.mModelInverse.Inverse(gContext.mModel);
+		gContext.mModelSourceInverse.Inverse(gContext.mModelSource);
 		gContext.mViewProjection = gContext.mViewMat * gContext.mProjectionMat;
 		gContext.mViewProjection = gContext.mViewMat * gContext.mProjectionMat;
 		gContext.mMVP = gContext.mModel * gContext.mViewProjection;
 		gContext.mMVP = gContext.mModel * gContext.mViewProjection;
 
 
@@ -1101,6 +1106,7 @@ namespace ImGuizmo
 	static void HandleTranslation(float *matrix, float *deltaMatrix, int& type, float *snap)
 	static void HandleTranslation(float *matrix, float *deltaMatrix, int& type, float *snap)
 	{
 	{
 		ImGuiIO& io = ImGui::GetIO();
 		ImGuiIO& io = ImGui::GetIO();
+		bool applyRotationLocaly = gContext.mMode == LOCAL || type == MOVE_SCREEN;
 
 
 		// move
 		// move
 		if (gContext.mbUsing)
 		if (gContext.mbUsing)
@@ -1125,8 +1131,18 @@ namespace ImGuizmo
 			if (snap)
 			if (snap)
 			{
 			{
 				vec_t cumulativeDelta = gContext.mModel.v.position + delta - gContext.mMatrixOrigin;
 				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;
 				delta = gContext.mMatrixOrigin + cumulativeDelta - gContext.mModel.v.position;
+
 			}
 			}
 
 
 			// compute matrix & delta
 			// compute matrix & delta
@@ -1134,6 +1150,8 @@ namespace ImGuizmo
 			deltaMatrixTranslation.Translation(delta);
 			deltaMatrixTranslation.Translation(delta);
 			if (deltaMatrix)
 			if (deltaMatrix)
 				memcpy(deltaMatrix, deltaMatrixTranslation.m16, sizeof(float) * 16);
 				memcpy(deltaMatrix, deltaMatrixTranslation.m16, sizeof(float) * 16);
+
+
 			matrix_t res = gContext.mModelSource * deltaMatrixTranslation;
 			matrix_t res = gContext.mModelSource * deltaMatrixTranslation;
 			*(matrix_t*)matrix = res;
 			*(matrix_t*)matrix = res;
 
 
@@ -1230,11 +1248,15 @@ namespace ImGuizmo
 			matrix_t deltaMatrixScale;
 			matrix_t deltaMatrixScale;
 			deltaMatrixScale.Scale(gContext.mScale * gContext.mScaleValueOrigin);
 			deltaMatrixScale.Scale(gContext.mScale * gContext.mScaleValueOrigin);
 			
 			
-			if (deltaMatrix)
-				memcpy(deltaMatrix, deltaMatrixScale.m16, sizeof(float) * 16);
 			matrix_t res = deltaMatrixScale * gContext.mModel;
 			matrix_t res = deltaMatrixScale * gContext.mModel;
 			*(matrix_t*)matrix = res;
 			*(matrix_t*)matrix = res;
 			
 			
+			if (deltaMatrix)
+			{
+				deltaMatrixScale.Scale(gContext.mScale);
+				memcpy(deltaMatrix, deltaMatrixScale.m16, sizeof(float) * 16);
+			}
+
 			if (!io.MouseDown[0])
 			if (!io.MouseDown[0])
 				gContext.mbUsing = false;
 				gContext.mbUsing = false;
 
 
@@ -1245,6 +1267,7 @@ namespace ImGuizmo
 	static void HandleRotation(float *matrix, float *deltaMatrix, int& type, float *snap)
 	static void HandleRotation(float *matrix, float *deltaMatrix, int& type, float *snap)
 	{
 	{
 		ImGuiIO& io = ImGui::GetIO();
 		ImGuiIO& io = ImGui::GetIO();
+		bool applyRotationLocaly = gContext.mMode == LOCAL || type == ROTATE_SCREEN;
 
 
 		if (!gContext.mbUsing)
 		if (!gContext.mbUsing)
 		{
 		{
@@ -1255,7 +1278,14 @@ namespace ImGuizmo
 				gContext.mCurrentOperation = type;
 				gContext.mCurrentOperation = type;
 				const vec_t rotatePlanNormal[] = { gContext.mModel.v.right, gContext.mModel.v.up, gContext.mModel.v.dir, -gContext.mCameraDir };
 				const vec_t rotatePlanNormal[] = { gContext.mModel.v.right, gContext.mModel.v.up, gContext.mModel.v.dir, -gContext.mCameraDir };
 				// pickup plan
 				// 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);
 				const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan);
 				vec_t localPos = gContext.mRayOrigin + gContext.mRayVector * len - gContext.mModel.v.position;
 				vec_t localPos = gContext.mRayOrigin + gContext.mRayVector * len - gContext.mModel.v.position;
@@ -1274,7 +1304,9 @@ namespace ImGuizmo
 				ComputeSnap(&gContext.mRotationAngle, &snapInRadian);
 				ComputeSnap(&gContext.mRotationAngle, &snapInRadian);
 			}
 			}
 			vec_t rotationAxisLocalSpace;
 			vec_t rotationAxisLocalSpace;
+			
 			rotationAxisLocalSpace.TransformVector(makeVect(gContext.mTranslationPlan.x, gContext.mTranslationPlan.y, gContext.mTranslationPlan.z, 0.f), gContext.mModelInverse);
 			rotationAxisLocalSpace.TransformVector(makeVect(gContext.mTranslationPlan.x, gContext.mTranslationPlan.y, gContext.mTranslationPlan.z, 0.f), gContext.mModelInverse);
+			rotationAxisLocalSpace.Normalize();
 
 
 			matrix_t deltaRotation;
 			matrix_t deltaRotation;
 			deltaRotation.RotationAxis(rotationAxisLocalSpace, gContext.mRotationAngle - gContext.mRotationAngleOrigin);
 			deltaRotation.RotationAxis(rotationAxisLocalSpace, gContext.mRotationAngle - gContext.mRotationAngleOrigin);
@@ -1283,8 +1315,18 @@ namespace ImGuizmo
 			matrix_t scaleOrigin;
 			matrix_t scaleOrigin;
 			scaleOrigin.Scale(gContext.mModelScaleOrigin);
 			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)
 			if (deltaMatrix)
 			{
 			{
@@ -1348,6 +1390,13 @@ namespace ImGuizmo
 		// set delta to identity 
 		// set delta to identity 
 		if (deltaMatrix)
 		if (deltaMatrix)
 			((matrix_t*)deltaMatrix)->SetToIdentity();
 			((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;
 		int type = NONE;
 		if (gContext.mbEnable)
 		if (gContext.mbEnable)
@@ -1399,6 +1448,23 @@ namespace ImGuizmo
 				directionUnary[normalIndex] - directionUnary[perpXIndex] - directionUnary[perpYIndex],
 				directionUnary[normalIndex] - directionUnary[perpXIndex] - directionUnary[perpYIndex],
 				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];
 			ImVec2 faceCoordsScreen[4];
 			for (unsigned int iCoord = 0; iCoord < 4; iCoord++)
 			for (unsigned int iCoord = 0; iCoord < 4; iCoord++)
 				faceCoordsScreen[iCoord] = worldToPos(faceCoords[iCoord] * 0.5f * invert, res);
 				faceCoordsScreen[iCoord] = worldToPos(faceCoords[iCoord] * 0.5f * invert, res);