Fix rotate issue

This commit is contained in:
2026-06-06 09:34:39 +08:00
parent d4b46b438c
commit 3b0250b882
3 changed files with 174 additions and 4 deletions
+42 -1
View File
@@ -1,9 +1,42 @@
#include "CreatePrimCommand.h"
#include "../../utils/Logger.h"
#include <pxr/usd/usd/prim.h>
#include <pxr/usd/usdGeom/xformCommonAPI.h>
#include <pxr/usd/usdGeom/metrics.h>
#include <pxr/usd/usdGeom/tokens.h>
namespace UsdLayerManager {
// ---------------------------------------------------------------------------
// ApplyCameraDefaultOrientation
//
// USD cameras always use +Y-up / look-down-Z in their own local frame.
// For a Y-up stage that is already the standard world forward direction, so
// the identity transform is fine.
//
// For a Z-up stage the identity transform would point the camera straight
// DOWN (world Z = up), which produces wrong orientation when the viewport
// switches to the prim, and wrong tumble/roll directions when navigating.
//
// Fix: rotate the camera +90° around its local X axis so that:
// camera local +Y (up) → world +Z (stage up axis) ✓
// camera local Z (view) → world +Y (horizontal "forward") ✓
// ---------------------------------------------------------------------------
static void ApplyCameraDefaultOrientation(pxr::UsdPrim& prim,
pxr::UsdStageRefPtr stage)
{
if (!prim.IsValid() || !stage) return;
bool isZUp = (pxr::UsdGeomGetStageUpAxis(stage) == pxr::UsdGeomTokens->z);
if (!isZUp) return; // Y-up default (identity) is already correct
pxr::UsdGeomXformCommonAPI xformAPI(prim);
// +90° around X: camera up aligns with world Z, view direction becomes +Y
xformAPI.SetRotate(pxr::GfVec3f(90.f, 0.f, 0.f),
pxr::UsdGeomXformCommonAPI::RotationOrderXYZ,
pxr::UsdTimeCode::Default());
}
CreatePrimCommand::CreatePrimCommand(pxr::UsdStageRefPtr stage,
const pxr::SdfPath& primPath,
const pxr::TfToken& typeName)
@@ -18,8 +51,16 @@ void CreatePrimCommand::Execute() {
if (!m_stage) return;
try {
pxr::UsdPrim prim = m_stage->DefinePrim(m_primPath, m_typeName);
if (!prim.IsValid())
if (!prim.IsValid()) {
LOG_ERROR("CreatePrimCommand: failed to define prim " + m_primPath.GetString());
return;
}
// Camera-specific initialisation: orient the prim so the camera looks
// in the correct "forward" direction for the stage's up-axis.
if (m_typeName == pxr::TfToken("Camera"))
ApplyCameraDefaultOrientation(prim, m_stage);
} catch (const std::exception& e) {
LOG_ERROR(std::string("CreatePrimCommand::Execute error: ") + e.what());
}