Skip to content

Commit 1371148

Browse files
jeongseok-metafacebook-github-bot
authored andcommitted
Replace Affine3 with Transform in collision geom (#559)
Summary: Pull Request resolved: #559 Reviewed By: juliencbmeta Differential Revision: D82118476 fbshipit-source-id: 39c23965a35da3fd66c646ea11eb5eb28047c965
1 parent 8772628 commit 1371148

File tree

15 files changed

+100
-73
lines changed

15 files changed

+100
-73
lines changed

momentum/character/character.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -356,8 +356,9 @@ CharacterT<T> CharacterT<T>::simplifySkeleton(const std::vector<bool>& activeJoi
356356
for (auto&& c : *result.collision) {
357357
const auto oldParent = c.parent;
358358
c.parent = result.jointMap[c.parent];
359-
c.transformation = targetBindState.jointState[c.parent].transform.inverse().toAffine3() *
360-
sourceBindState.jointState[oldParent].transform.toAffine3() * c.transformation;
359+
c.transformation =
360+
(targetBindState.jointState[c.parent].transform.inverse() *
361+
sourceBindState.jointState[oldParent].transform * c.transformation);
361362
}
362363
}
363364

momentum/character/character_utility.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ std::unique_ptr<CollisionGeometry> scale(
7171

7272
auto result = std::make_unique<CollisionGeometry>(*geom);
7373
for (auto& capsule : (*result)) {
74-
capsule.transformation.translation() *= scale;
74+
capsule.transformation.translation *= scale;
7575
capsule.radius *= scale;
7676
capsule.length *= scale;
7777
}

momentum/character/collision_geometry.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <momentum/character/types.h>
1111
#include <momentum/common/memory.h>
1212
#include <momentum/math/constants.h>
13+
#include <momentum/math/transform.h>
1314
#include <momentum/math/utility.h>
1415

1516
namespace momentum {
@@ -24,7 +25,7 @@ struct TaperedCapsuleT {
2425

2526
/// Transformation defining the orientation and starting point relative to the parent coordinate
2627
/// system.
27-
Affine3<S> transformation;
28+
TransformT<S> transformation;
2829

2930
/// Radii at the two endpoints of the capsule.
3031
Vector2<S> radius;
@@ -36,7 +37,7 @@ struct TaperedCapsuleT {
3637
S length;
3738

3839
TaperedCapsuleT()
39-
: transformation(Affine3<S>::Identity()),
40+
: transformation(TransformT<S>()),
4041
radius(Vector2<S>::Zero()),
4142
parent(kInvalidIndex),
4243
length(S(0)) {

momentum/character/collision_geometry_state.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ void CollisionGeometryStateT<T>::update(
2626
for (size_t i = 0; i < numElements; ++i) {
2727
const auto& tc = collisionGeometry[i];
2828
const auto& js = skeletonState.jointState[tc.parent];
29-
const Affine3<T> transform = js.transform.toAffine3() * tc.transformation.cast<T>();
30-
origin[i] = transform.translation();
31-
direction[i].noalias() = transform.linear().col(0) * tc.length;
29+
const TransformT<T> transform = js.transform * tc.transformation.cast<T>();
30+
origin[i] = transform.translation;
31+
direction[i].noalias() = transform.getAxisX() * transform.scale * tc.length;
3232
radius[i].noalias() = tc.radius.cast<T>() * js.transform.scale;
3333
delta[i] = radius[i][1] - radius[i][0];
3434
}

momentum/gui/rerun/logger.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -350,13 +350,12 @@ void logCollisionGeometry(
350350
for (const auto& cg : collisionGeometry) {
351351
const auto& js = skeletonState.jointState.at(cg.parent);
352352

353-
const Affine3f tf = js.transform.toAffine3() * cg.transformation;
354-
// Rerun capsule's axis is along the Z-axis while Momentum's is along the X-axis, so we need to
355-
// rotate 90 degrees around the Y-axis to align the axes.
356-
const Quaternionf q =
357-
Quaternionf(tf.linear()) * Eigen::AngleAxisf(0.5f * pi(), Vector3f::UnitY());
353+
const float halfX = 0.5f * cg.length;
354+
const Transform tf =
355+
js.transform * cg.transformation * Transform::makeTranslation({halfX, 0, 0});
356+
const Quaternionf& q = tf.rotation;
358357

359-
translations.push_back(toRerunPosition3D(tf.translation()));
358+
translations.push_back(toRerunPosition3D(tf.translation));
360359
quaternions.emplace_back(rerun::Quaternion::from_xyzw(q.x(), q.y(), q.z(), q.w()));
361360
lengths.emplace_back(cg.length);
362361
// TODO: Rerun doesn't support capsules with different radii (i.e. tapered capsule) yet

momentum/io/fbx/fbx_io.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,11 @@ void createCollisionGeometryNodes(
134134
.Set(collision.radius[1]);
135135

136136
collisionNode->LclTranslation.Set(FbxVector4(
137-
collision.transformation.translation().x(),
138-
collision.transformation.translation().y(),
139-
collision.transformation.translation().z()));
137+
collision.transformation.translation.x(),
138+
collision.transformation.translation.y(),
139+
collision.transformation.translation.z()));
140140
const Vector3f rot = rotationMatrixToEulerXYZ<float>(
141-
collision.transformation.rotation(), EulerConvention::Extrinsic);
141+
collision.transformation.rotation.toRotationMatrix(), EulerConvention::Extrinsic);
142142
collisionNode->LclRotation.Set(FbxDouble3(toDeg(rot.x()), toDeg(rot.y()), toDeg(rot.z())));
143143
collisionNode->LclScaling.Set(FbxDouble3(1));
144144

momentum/io/gltf/gltf_builder.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -714,9 +714,8 @@ void addCollisionsToModel(
714714
// add values for the tapered capsule
715715
node.name = character.skeleton.joints.at(col.parent).name + "_col";
716716

717-
const Quaternionf rot(col.transformation.linear());
718-
node.rotation = fromMomentumQuaternionf(rot);
719-
const auto translation = fromMomentumVec3f(col.transformation.translation());
717+
node.rotation = fromMomentumQuaternionf(col.transformation.rotation);
718+
const auto translation = fromMomentumVec3f(col.transformation.translation);
720719
node.translation = {translation[0], translation[1], translation[2]};
721720

722721
// add extra properties

momentum/io/gltf/gltf_io.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ nlohmann::json getMomentumExtension(const nlohmann::json& extensionsAndExtras) {
5959
TaperedCapsule createCollisionCapsule(const fx::gltf::Node& node, const nlohmann::json& extension) {
6060
TaperedCapsule tc;
6161
tc.parent = kInvalidIndex;
62-
tc.transformation = Affine3f::Identity();
63-
tc.transformation.linear() = toMomentumQuaternionf(node.rotation).toRotationMatrix();
64-
tc.transformation.translation() = toMomentumVec3f(node.translation);
62+
tc.transformation = Transform();
63+
tc.transformation.rotation = toMomentumQuaternionf(node.rotation);
64+
tc.transformation.translation = toMomentumVec3f(node.translation);
6565

6666
try {
6767
tc.length = extension["length"];

momentum/io/legacy_json/legacy_json_io.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -396,8 +396,7 @@ CollisionGeometry legacyCollisionToMomentum(const nlohmann::json& legacyCollisio
396396
TaperedCapsule capsule;
397397

398398
if (capsuleJson.contains("transformation")) {
399-
TransformT<float> transform = jsonToTransform<float>(capsuleJson["transformation"]);
400-
capsule.transformation = transform.toAffine3();
399+
capsule.transformation = jsonToTransform<float>(capsuleJson["transformation"]);
401400
}
402401

403402
if (capsuleJson.contains("radius")) {
@@ -425,8 +424,7 @@ nlohmann::json momentumCollisionToLegacy(const CollisionGeometry& collision) {
425424
for (const auto& capsule : collision) {
426425
nlohmann::json capsuleJson;
427426

428-
TransformT<float> transform = TransformT<float>::fromAffine3(capsule.transformation);
429-
capsuleJson["transformation"] = transformToJson(transform);
427+
capsuleJson["transformation"] = transformToJson(capsule.transformation);
430428
capsuleJson["radius"] = eigenToJsonArray(capsule.radius);
431429
capsuleJson["parent"] = capsule.parent;
432430
capsuleJson["length"] = capsule.length;

momentum/math/transform.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,27 @@ struct TransformT {
158158
return toRotationMatrix() * scale;
159159
}
160160

161+
/// Gets the X axis of the rotation
162+
[[nodiscard]] Vector3<T> getAxisX() const {
163+
// Optimized version of Eigen::Quaternion::toRotationMatrix()
164+
Vector3<T> axis;
165+
166+
const T ty = T(2) * rotation.y();
167+
const T tz = T(2) * rotation.z();
168+
const T twy = ty * rotation.w();
169+
const T twz = tz * rotation.w();
170+
const T txy = ty * rotation.x();
171+
const T txz = tz * rotation.x();
172+
const T tyy = ty * rotation.y();
173+
const T tzz = tz * rotation.z();
174+
175+
axis[0] = T(1) - (tyy + tzz);
176+
axis[1] = txy + twz;
177+
axis[2] = txz - twy;
178+
179+
return axis;
180+
}
181+
161182
/// Applies full transform to a point
162183
[[nodiscard]] Vector3<T> transformPoint(const Vector3<T>& pt) const {
163184
return translation + rotation * (scale * pt).eval();
@@ -179,6 +200,14 @@ struct TransformT {
179200
this->rotation.template cast<T2>(),
180201
static_cast<T2>(this->scale));
181202
}
203+
204+
/// Checks if this transform is approximately equal to another
205+
[[nodiscard]] bool isApprox(
206+
const TransformT<T>& other,
207+
T tol = Eigen::NumTraits<T>::dummy_precision()) const {
208+
// TODO: Improve
209+
return toAffine3().isApprox(other.toAffine3(), tol);
210+
}
182211
};
183212

184213
template <typename T>

0 commit comments

Comments
 (0)