ImGuizmo란 무엇인가?
ImGuizmo는 Dear ImGui 위에서 동작하는 간단한 변환 도구(Transform Gizmo)입니다. 개발자들이 3D 모델링 도구(예: Blender, Unity)에서 볼 수 있는 이동(Translate), 회전(Rotate), 크기 조정(Scale) 기능을 게임 엔진이나 편집기에 통합할 수 있도록 도와줍니다. 주요 기능은 다음과 같습니다:
1.
Translate, Rotate, Scale 기능 지원
2.
세계 좌표계(World)와 로컬 좌표계(Local) 모드 지원
3.
스냅(Snap) 기능으로 정밀한 변환 지원
4.
Orthographic(직교) 및 Perspective(투시) 카메라 지원
코드 분석
1. 기본 설정
ImGuizmo::SetOrthographic(false);
ImGuizmo::SetDrawlist();
ImGuizmo::SetRect(mViewportBounds[0].x, mViewportBounds[0].y
, mViewportBounds[1].x - mViewportBounds[0].x, mViewportBounds[1].y - mViewportBounds[0].y);
C++
복사
•
SetOrthographic: 카메라가 직교(Orthographic) 투영이 아닌 투시(Perspective) 투영을 사용하도록 설정합니다.
•
SetDrawlist: 현재 ImGui 컨텍스트에서 ImGuizmo가 그려질 위치를 지정합니다.
•
SetRect: 기즈모가 표시될 화면 영역을 설정합니다. mViewportBounds는 화면에서 뷰포트의 시작점(좌측 상단)과 크기(가로, 세로)를 나타냅니다.
2. 카메라와 대상 객체 설정
const ya::math::Matrix& viewMatrix = ya::renderer::mainCamera->GetViewMatrix();
const ya::math::Matrix& projectionMatrix = ya::renderer::mainCamera->GetProjectionMatrix();
ya::Transform* transform = selectedObject->GetComponent<ya::Transform>();
ya::math::Matrix worldMatrix = transform->GetWorldMatrix();
C++
복사
•
viewMatrix: 카메라의 뷰 행렬(View Matrix). 월드 좌표를 카메라 좌표로 변환합니다.
•
projectionMatrix: 카메라의 투영 행렬(Projection Matrix). 카메라 좌표를 클립 공간으로 변환합니다.
•
worldMatrix: 선택된 객체의 변환 행렬. 해당 객체의 위치, 회전, 크기를 나타냅니다.
3. 스냅(Snapping) 설정
bool snap = ya::Input::GetKey(ya::eKeyCode::Leftcontrol);
float snapValue = 0.5f;
if (mGuizmoType == ImGuizmo::OPERATION::ROTATE)
snapValue = 45.0f;
float snapValues[3] = { snapValue, snapValue, snapValue };
C++
복사
•
snap: 사용자가 Ctrl 키를 누를 때 스냅 기능을 활성화합니다.
•
snapValue: 이동의 경우 0.5, 회전의 경우 45도로 스냅 설정.
•
snapValues: 변환 작업(이동, 회전, 크기 조정)을 3차원 벡터로 지정.
4. ImGuizmo 변환 수행
ImGuizmo::Manipulate(*viewMatrix.m, *projectionMatrix.m
, static_cast<ImGuizmo::OPERATION>(mGuizmoType) , ImGuizmo::LOCAL, *worldMatrix.m
, nullptr, snap ? snapValues : nullptr);
C++
복사
•
viewMatrix.m: 카메라의 뷰 행렬을 전달.
•
projectionMatrix.m: 카메라의 투영 행렬을 전달.
•
mGuizmoType: 현재 선택된 변환 유형(TRANSLATE, ROTATE, SCALE).
•
ImGuizmo::LOCAL: 변환을 로컬 좌표계(Local Space) 기준으로 수행.
•
snapValues: 스냅이 활성화된 경우 스냅 벡터를 사용.
5. 변환된 결과 반영
if (ImGuizmo::IsUsing())
{
float translation[3];
float rotation[3];
float scale[3];
ImGuizmo::DecomposeMatrixToComponents(*worldMatrix.m, translation, rotation, scale);
ya::math::Vector3 deltaRotation = Vector3(rotation) - transform->GetRotation();
deltaRotation = transform->GetRotation() + deltaRotation;
transform->SetScale(Vector3(scale));
transform->SetRotation(Vector3(deltaRotation));
transform->SetPosition(Vector3(translation));
}
C++
복사
•
ImGuizmo::IsUsing(): 사용자가 기즈모를 조작 중인 경우 true.
•
DecomposeMatrixToComponents: 월드 행렬에서 변환(Translation), 회전(Rotation), 크기(Scale)를 분리.
•
deltaRotation: 현재 회전 값에서 새로운 회전 값을 뺀 후, 델타 값만큼 회전을 업데이트.
•
SetScale, SetRotation, SetPosition: 분리된 변환 데이터를 객체의 변환 컴포넌트에 반영.
이 코드가 하는 일
1.
화면의 특정 뷰포트 내에서 선택된 객체를 대상으로 기즈모를 렌더링.
2.
사용자가 기즈모를 조작(이동, 회전, 크기 조정)하면, 변환된 결과를 객체의 변환 데이터로 반영.
3.
스냅 기능을 통해 정밀한 이동이나 회전을 지원.
확장 가능성
1.
좌표계 전환:
•
ImGuizmo::LOCAL 대신 ImGuizmo::WORLD로 설정하면 월드 좌표계를 기준으로 작업 가능.
2.
다중 선택:
•
여러 객체를 동시에 변환하려면 반복문을 통해 각 객체에 Manipulate 호출.
3.
UI 개선:
•
ImGui와 연동하여 사용자 설정(스냅 크기, 좌표계 모드 등)을 동적으로 변경할 수 있는 UI 추가.