CedricGuillemet / ImGuizmo

Immediate mode 3D gizmo for scene editing and other controls based on Dear Imgui

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Issues with rotations

jkinz3 opened this issue · comments

I'm having an issue with rotations.
Basically I want to use ImGuizmo with Z being up and X being forward. If that's not possible, please let me know.
When I run the code, everything freaks out when I rotate the model to Y = -90. I assume it is an issue with my code but I cannot find out what's going on

void Game::TickGizmo(Model* Mesh)
{
	ImGuizmo::Enable(true);
	ViewMatrix = MyCamera->GetViewMatrix();
	ProjectionMatrix = MyCamera->GetProjectionMatrix();
	MeshTransformMatrix = MyModel->GetTransformationMatrix();
	ImVec2 viewportPanelSize = ImGui::GetContentRegionAvail();
	ImGuiIO& io = ImGui::GetIO();
	ImGuizmo::SetOrthographic(false);
	ImGuizmo::BeginFrame();
	ImGuizmo::SetRect(0, 0, io.DisplaySize.x, io.DisplaySize.y);
	ImGuizmo::DrawCubes(&ViewMatrix.m[0][0], &ProjectionMatrix.m[0][0], *MeshTransformMatrix.m, 1);
	ImGuizmo::DrawGrid(*ViewMatrix.m, *ProjectionMatrix.m, *MeshTransformMatrix.m, 500);
	ImGuizmo::Manipulate(*ViewMatrix.m, *ProjectionMatrix.m, mCurrentGizmoOperation, mCurrentGizmoMode, *MeshTransformMatrix.m);
	
	if (ImGuizmo::IsUsing())
	{
	Vector3 NewTrans;
	Vector3 NewRot;
	Vector3 NewScale;
	float matrixTrans[3];
	float matrixRot[3];
	float matrixScale[3];

	ImGuizmo::DecomposeMatrixToComponents(*MeshTransformMatrix.m, matrixTrans, matrixRot, matrixScale);
	NewTrans = Vector3(matrixTrans);
	NewRot = Vector3(matrixRot[0], matrixRot[1], matrixRot[2]);
	NewScale = Vector3(matrixScale[0], matrixScale[1], matrixScale[2]);
	MyModel->SetTransformation(NewTrans, NewRot, NewScale);
	}
	ImGui::End();
}

HALP

To be sure it's in your code and not the gizmo, can you try to apply the gizmo matrix instead of recomposing it from the tr/rt/sc values?
This can happen if the order of rotation are not applied in the same order as imguizmo.
To check that, when you compute the matrix on your side, does it give you the same result as the matrix recomposition done with this function ?

void RecomposeMatrixFromComponents(const float* translation, const float* rotation, const float* scale, float* matrix)

@CedricGuillemet
Thank you for your response.
I'm using the SimpleMath library that serves as a wrapper for DirectXMath as a part of the DirectXToolkit.
As such, i've narrowed it down to this function
Matrix::CreateFromYawPitchRoll(float yaw, float pitch, float roll)
What I did was set the model's Y rotation to -90 using ImGui::DragFloat3. Then I switched to the rotation widget and did a single click on the Y axis to recreate the bug. The X and Z values immediately jump to -180 each.
Looking at the results from this function, it appears that this is the rotation matrix it returns
`{0, 0,-1, 0}

{0, 1, 0, 0}

{1, 0, 0, 0}

{0, 0, 0, 1}`

While using the ImGuizmo::RecomposeMatrixFromComponents function returns this:

`{0, 0, 1, 0}

{0, 1, 0, 0}

{-1, 0, 0, 0}

{0, 0, 0, 1}`

So it appears that there is a difference between how ImGuizmo creates this matrix and how DirectXMath does it.
I'm still learning so it could very well be my code

Here is the remarks from MS on the DirectXMath library

Angles are measured clockwise when looking along the rotation axis toward the origin. This is a left-handed coordinate system. To use right-handed coordinates, negate all three angles.
The order of transformations is roll first, then pitch, and then yaw. The rotations are all applied in the global coordinate frame.
Does ImGuizmo apply rotations in a different order? How can I adjust it?

I was able to fix this issue. If anyone gets the same issue, it's due to the Matrix::CreateFromYawPitchRoll(float yaw, float pitch, float roll)
This applies the rotations in order of Roll > Pitch > Yaw. The issue was because I was using void RecomposeMatrixFromComponents(const float* translation, const float* rotation, const float* scale, float* matrix) for the gizmo but using Matrix::CreateFromYawPitchRoll(float yaw, float pitch, float roll) to generate the transformation matrix for the rest of the rendering code.
The solution was to avoid using Matrix::CreateFromYawPitchRoll(float yaw, float pitch, float roll) entirely and composing the transform matrix by using void RecomposeMatrixFromComponents(const float* translation, const float* rotation, const float* scale, float* matrix) for all purposes. I'm sure there would be a way to input the parameters to make it compatible but I was not able to figure it out.

I have a similar issue @jkinz3
No workaround except don't use CreateFromYawPitchRoll (I can't)?