Add opt-in transform orthonormalization to the Collada importer#138
Conversation
Some exporters (notably Autodesk FBX-to-Collada and OpenCollada) bake enough floating-point rounding error into <matrix> transforms that the rotational 3x3 block is no longer orthonormal. On skeletal import this trips Ardor3D's "supplied transform with non-rotational matrices" warning flood and degrades the rotation extracted for animation channels (issue #32). Add ColladaImporter.setOrthonormalizeTransforms(boolean), off by default. When enabled, the upper-left 3x3 of each baked node and animation channel transform is cleaned with Matrix4.orthonormalizeLocal() (added in #137) before it becomes a Transform, with the translation preserved. A rank-deficient block is left as-is with a warning rather than aborting the whole load. The importer is now threaded into ColladaAnimUtils so it can read the flag, mirroring ColladaNodeUtils/ColladaMaterialUtils. Enabling the flag discards any scale or shear carried in those matrices, so it is opt-in and documented as such. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Warning Review limit reached
More reviews will be available in 11 minutes and 13 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
bakeTransforms (ColladaAnimUtils) and getNodeTransforms (ColladaNodeUtils) each fetched two Matrix4 instances via Matrix4.fetchTempInstance() but never released them, leaking them from the per-thread math pool on every call. Wrap each body in try/finally so both temps are returned to the pool on all paths, including exceptions. finalMat is still fully consumed by fromHomogeneousMatrix in the return expression before the finally runs, so there is no use-after-release. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
What
Adds
ColladaImporter.setOrthonormalizeTransforms(boolean)(off by default). When enabled, the rotational upper-left 3×3 of every baked node and animation-channel transform is cleaned withMatrix4.orthonormalizeLocal()(Gram-Schmidt, added in #137) right before it becomes aTransform— preserving the translation column.Wiring:
ColladaImporter, following the existingsetLoadTextures/setFlipTransparencypattern.fromHomogeneousMatrixchoke points:ColladaNodeUtils.getNodeTransforms(node/joint transforms) andColladaAnimUtils.bakeTransforms(animation samples).ColladaAnimUtilsis now handed theColladaImporterin its constructor so it can read the flag, mirroring howColladaNodeUtilsandColladaMaterialUtilsalready take it.Why
Autodesk FBX→Collada and OpenCollada exporters frequently bake enough floating-point rounding error into
<matrix>transforms that the 3×3 rotational block failsisOrthonormal(). On skeletal import this trips the long-standing"supplied transform with non-rotational matrices. May have unexpected results."warning flood and degrades the rotation extracted for each channel. This gives users a one-call opt-in to clean those matrices at import. Addresses the importer half of #32.Design notes
<matrix>, and we can't tell intentional shear from rounding noise — so it's off by default and documented as "only enable when your source encodes pure rotation + translation." This matches the conclusion reached in the Resolve Non-rotational matrices at import time in Animation Manager from collada #32 discussion (don't auto-enforce).orthonormalizeLocal()throwArithmeticException; that's caught per-transform and the matrix is left as-is with a warning, rather than aborting the whole load.Tests
New
TestColladaOrthonormalizeloads an inline.daewhose single node carries a slightly-skewed near-identity<matrix>plus a translation:isRotationMatrix()true) and the(5, 6, 7)translation is preserved.Full
ardor3d-colladasuite green (7 tests, 0 failures). The node path is covered directly; the animation-channel path shares the identical mechanism at the sibling choke point.Follow-up
Depends on #137 (merged). Issue #32 can be closed once this lands; I'll leave the issue comment to you.
🤖 Generated with Claude Code
Update: temp-pool cleanup
Folded in a fix for a pre-existing leak in the two methods this PR already touches:
bakeTransformsandgetNodeTransformseach fetched twoMatrix4.fetchTempInstance()temps and never released them. Their bodies are now wrapped intry/finallyso both temps are returned to the per-thread pool on all paths (including exceptions).finalMatis still consumed byfromHomogeneousMatrixin thereturnexpression before thefinallyruns, so there is no use-after-release.