Skip to content

Commit cf28342

Browse files
adlarkinahcorde
andauthored
USD -> SDF transform fixes (#924)
Signed-off-by: Ashton Larkin <42042756+adlarkin@users.noreply.github.com> Co-authored-by: ahcorde <ahcorde@gmail.com>
1 parent 5f6f333 commit cf28342

File tree

4 files changed

+103
-217
lines changed

4 files changed

+103
-217
lines changed

test/usd/nested_transforms.usda

+14
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,18 @@ def "transforms"
1919
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:rotateXYZ"]
2020
}
2121
}
22+
23+
def Xform "nested_transforms_ZYX"
24+
{
25+
float3 xformOp:rotateZYX = (90, 0, 0)
26+
double3 xformOp:translate = (1, 0, 0)
27+
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:rotateZYX"]
28+
29+
def Xform "child_transform"
30+
{
31+
float3 xformOp:rotateZYX = (0, 0, 0)
32+
double3 xformOp:translate = (1, 0, 0)
33+
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:rotateZYX"]
34+
}
35+
}
2236
}

usd/include/sdf/usd/usd_parser/USDTransforms.hh

+7-36
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@ namespace sdf
5353
/// This might contain scale, translate or rotation operations
5454
/// The booleans are used to check if there is a transform defined
5555
/// in the schema
56-
/// Rotation is splitted in a vector because this might be defined
57-
/// as a rotation of 3 angles (ZYX, XYZ, etc).
5856
class IGNITION_SDFORMAT_USD_VISIBLE UDSTransforms
5957
{
6058
/// \brief Default constructor
@@ -68,13 +66,10 @@ namespace sdf
6866
/// \return A 3D vector with the scale
6967
public: const ignition::math::Vector3d Scale() const;
7068

71-
/// \brief Rotation
72-
/// \return Return a vector with all the rotations
73-
/// If RotationXYZ or RotationZYY is true, this method will return a
74-
/// vector of 3 quaternions, Rotation<axis1><axis2><axis3> with the first
75-
/// quaternion being rotation <axis1>, the second being rotation about
76-
/// <axis2>, and the third being rotation about <axis3>
77-
public: const std::vector<ignition::math::Quaterniond> Rotations() const;
69+
/// \brief Get the Rotation
70+
/// \return Return The rotation, if one exists. If no rotation exists,
71+
/// std::nullopt is returned
72+
public: const std::optional<ignition::math::Quaterniond> Rotation() const;
7873

7974
/// \brief Set translate
8075
/// \param[in] _translate Translate to set
@@ -84,33 +79,9 @@ namespace sdf
8479
/// \param[in] _scale Scale to set
8580
public: void SetScale(const ignition::math::Vector3d &_scale);
8681

87-
/// \brief Add rotation
88-
/// \param[in] _q Quaternion to add to the list of rotations
89-
public: void AddRotation(const ignition::math::Quaterniond &_q);
90-
91-
/// \brief True if there is a rotation ZYX defined or false otherwise
92-
public: bool RotationZYX() const;
93-
94-
/// \brief True if there is a rotation XYZ defined or false otherwise
95-
public: bool RotationXYZ() const;
96-
97-
/// \brief True if there is a rotation (as a quaternion) defined
98-
/// or false otherwise
99-
public: bool Rotation() const;
100-
101-
/// \brief Set if there is any rotation ZYX defined
102-
/// RotationZYX is used to determine the order of stored rotations
103-
/// If RotationZYX is true, then Rotation should be True too
104-
/// If Rotation is false, then RotationZYX cannot be true
105-
/// \param[in] _rotationZYX If the rotation is ZYX (true) or not (false)
106-
public: void SetRotationZYX(bool _rotationZYX);
107-
108-
/// \brief Set if there is any rotation XYZ defined
109-
/// RotationXYZ is used to determine the order of stored rotations
110-
/// If RotationXYZ is true, then Rotation should be True too
111-
/// If Rotation is false, then RotationXYZ cannot be true
112-
/// \param[in] _rotationXYZ If the rotation is XYZ (true) or not (false)
113-
public: void SetRotationXYZ(bool _rotationXYZ);
82+
/// \brief Set rotation
83+
/// \param[in] _q Quaternion that defines the rotation
84+
public: void SetRotation(const ignition::math::Quaterniond &_q);
11485

11586
/// \brief Private data pointer.
11687
IGN_UTILS_IMPL_PTR(dataPtr)

usd/src/usd_parser/USDTransforms.cc

+17-85
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717

1818
#include "sdf/usd/usd_parser/USDTransforms.hh"
1919

20+
#include <optional>
21+
#include <utility>
22+
2023
#include <ignition/math/Pose3.hh>
2124
#include <ignition/math/Vector3.hh>
2225

@@ -49,16 +52,10 @@ class UDSTransforms::Implementation
4952
public: ignition::math::Vector3d scale{1, 1, 1};
5053

5154
/// \brief Rotation of the schema
52-
public: std::vector<ignition::math::Quaterniond> q;
55+
public: std::optional<ignition::math::Quaterniond> q = std::nullopt;
5356

5457
/// \brief Translation of the schema
5558
public: ignition::math::Vector3d translate{0, 0, 0};
56-
57-
/// \brief True if there is a rotation ZYX defined or false otherwise
58-
public: bool isRotationZYX = false;
59-
60-
/// \brief True if there is a rotation XYZ defined or false otherwise
61-
public: bool isRotationXYZ = false;
6259
};
6360

6461
/////////////////////////////////////////////////
@@ -80,8 +77,7 @@ const ignition::math::Vector3d UDSTransforms::Scale() const
8077
}
8178

8279
//////////////////////////////////////////////////
83-
const std::vector<ignition::math::Quaterniond>
84-
UDSTransforms::Rotations() const
80+
const std::optional<ignition::math::Quaterniond> UDSTransforms::Rotation() const
8581
{
8682
return this->dataPtr->q;
8783
}
@@ -101,44 +97,10 @@ void UDSTransforms::SetScale(
10197
}
10298

10399
//////////////////////////////////////////////////
104-
void UDSTransforms::AddRotation(
100+
void UDSTransforms::SetRotation(
105101
const ignition::math::Quaterniond &_q)
106102
{
107-
this->dataPtr->q.push_back(_q);
108-
}
109-
110-
//////////////////////////////////////////////////
111-
bool UDSTransforms::RotationZYX() const
112-
{
113-
return this->dataPtr->isRotationZYX;
114-
}
115-
116-
//////////////////////////////////////////////////
117-
bool UDSTransforms::RotationXYZ() const
118-
{
119-
return this->dataPtr->isRotationXYZ;
120-
}
121-
122-
//////////////////////////////////////////////////
123-
bool UDSTransforms::Rotation() const
124-
{
125-
return !this->dataPtr->q.empty();
126-
}
127-
128-
//////////////////////////////////////////////////
129-
void UDSTransforms::SetRotationZYX(bool _rotationZYX)
130-
{
131-
this->dataPtr->isRotationZYX = _rotationZYX;
132-
if (_rotationZYX)
133-
this->dataPtr->isRotationXYZ = false;
134-
}
135-
136-
//////////////////////////////////////////////////
137-
void UDSTransforms::SetRotationXYZ(bool _rotationXYZ)
138-
{
139-
this->dataPtr->isRotationXYZ = _rotationXYZ;
140-
if (_rotationXYZ)
141-
this->dataPtr->isRotationZYX = false;
103+
this->dataPtr->q = _q;
142104
}
143105

144106
//////////////////////////////////////////////////
@@ -191,41 +153,11 @@ void GetAllTransforms(
191153
child.Pos().Z() * t.Scale()[2]);
192154
}
193155

194-
if (!t.RotationZYX() && !t.RotationXYZ())
156+
if (t.Rotation())
195157
{
196-
if (t.Rotation())
197-
{
198-
pose.Rot() = t.Rotations()[0];
199-
}
200-
_tfs.push_back(pose);
201-
}
202-
else
203-
{
204-
ignition::math::Pose3d poseZ = ignition::math::Pose3d(
205-
ignition::math::Vector3d(0, 0, 0), t.Rotations()[2]);
206-
ignition::math::Pose3d poseY = ignition::math::Pose3d(
207-
ignition::math::Vector3d(0, 0, 0), t.Rotations()[1]);
208-
ignition::math::Pose3d poseX = ignition::math::Pose3d(
209-
ignition::math::Vector3d(0, 0, 0), t.Rotations()[0]);
210-
211-
ignition::math::Pose3d poseT = ignition::math::Pose3d(
212-
t.Translation() * metersPerUnit,
213-
ignition::math::Quaterniond(1, 0, 0, 0));
214-
215-
if (t.RotationZYX())
216-
{
217-
_tfs.push_back(poseZ);
218-
_tfs.push_back(poseY);
219-
_tfs.push_back(poseX);
220-
}
221-
else if (t.RotationXYZ())
222-
{
223-
_tfs.push_back(poseX);
224-
_tfs.push_back(poseY);
225-
_tfs.push_back(poseZ);
226-
}
227-
_tfs.push_back(poseT);
158+
pose.Rot() = t.Rotation().value();
228159
}
160+
_tfs.push_back(pose);
229161
parent = parent.GetParent();
230162
}
231163

@@ -297,12 +229,10 @@ UDSTransforms ParseUSDTransform(const pxr::UsdPrim &_prim)
297229
if (op == kXFormOpRotateZYX)
298230
{
299231
attribute = _prim.GetAttribute(pxr::TfToken(kXFormOpRotateZYX));
300-
t.SetRotationZYX(true);
301232
}
302233
else
303234
{
304235
attribute = _prim.GetAttribute(pxr::TfToken(kXFormOpRotateXYZ));
305-
t.SetRotationXYZ(true);
306236
}
307237
if (attribute.GetTypeName().GetCPPTypeName() == kGfVec3fString)
308238
{
@@ -324,9 +254,11 @@ UDSTransforms ParseUSDTransform(const pxr::UsdPrim &_prim)
324254
qY = ignition::math::Quaterniond(0, angleY.Normalized().Radian(), 0);
325255
qZ = ignition::math::Quaterniond(0, 0, angleZ.Normalized().Radian());
326256

327-
t.AddRotation(qX);
328-
t.AddRotation(qY);
329-
t.AddRotation(qZ);
257+
if (op == kXFormOpRotateZYX)
258+
{
259+
std::swap(angleX, angleZ);
260+
}
261+
t.SetRotation((qX * qY) * qZ);
330262
}
331263
else if (op == kXFormOpTranslate)
332264
{
@@ -370,7 +302,7 @@ UDSTransforms ParseUSDTransform(const pxr::UsdPrim &_prim)
370302
rotationQuad.GetImaginary()[0],
371303
rotationQuad.GetImaginary()[1],
372304
rotationQuad.GetImaginary()[2]);
373-
t.AddRotation(q);
305+
t.SetRotation(q);
374306
}
375307

376308
if (op == kXFormOpTransform)
@@ -397,7 +329,7 @@ UDSTransforms ParseUSDTransform(const pxr::UsdPrim &_prim)
397329
rotQuat.GetImaginary()[1],
398330
rotQuat.GetImaginary()[2]
399331
);
400-
t.AddRotation(q);
332+
t.SetRotation(q);
401333
}
402334
}
403335
return t;

0 commit comments

Comments
 (0)