tl;dr vtkGLTFExporter ignores vtkAssembly in its export operation. If I create an assembly with various parts (where each part’s pose is relative to the hierarchy) and pose the assembly root, exporting that to a gltf will not create an empty node for the assembly, and each of the parts are output without the root node’s transform contributing.
So, in this case, one would expect the vtkAssembly should result in a node (without “mesh” and without “camera”), but with a transform and one or more children.
The view matrix is derived from the global transform of the node containing the camera with the scaling ignored. If the node’s global transform is identity, the location of the camera is at the origin.
This has nothing to do with node transforms, only the camera arrays.
Edit: sorry, for clarity, to the best of my understanding, vtkMatrix4x4* mat = ren->GetActiveCamera()->GetModelViewTransformMatrix(); is going to give us the properly transformed matrix in the event that there is a camera that is a child of something. But the only matrix that was getting inverted there was for the camera, it should not be affecting the other items in the scene being exported.
While I haven’t confirmed this yet, it’s worth noting this will probably also impact glTF importing as well. If I have a hierarchy rooted at an empty node with a non-identity transform, the other nodes will probably not have the correct pose w.r.t. the file’s frame.
And, by induction, any hierarchy with greater depth, such that the world transform of the parent node is not the identity, would suffer from having the wrong pose in the file frame. I’ll run some tests today and get back with some more concrete results.
I just did a quick test on a glTF file that had the following hierarchy:
empty
|_ mesh 1
|_ mesh 2
|_ mesh 3
All nodes had non-identity transforms. If my hypothesis about import problems had been true, I would’ve expected all the pieces to be misaligned (as each of their poses depended on the concatenation of the full tree), but it presents itself correctly. Happy to be wrong.
If you want to explore yourself, I’ve got the glTF - a small pyramid that when imported correctly should be sitting on the world’s xy-plane, centered on the origin (as shown in the image).
Unfortunately, I’m classified as a “new user” and can’t attach the zipped up .glTF. Is there a good place to upload to?
Oh, sorry. That is correct. glTF is uses a y-up coordinate system. The domains I work routinely play in (Blender, Drake) live in a z-up world. So, this y-up is an honest and accurate result based strictly on the file contents. I’d addressed the rotation to z-up so long ago, I just take it for granted.
And speaking of taking it for granted, the importer and exporter would benefit from a configuration indicating whether things need to be rotated. Given glTF is definitely documented to be y-up, I suppose it would be enough if the caller could report what world the caller lives in and then VTK could perform any rotations necessary to get it into a y-up world as it goes.
If that information is contained in the file, VTK should respect it (and there may be a bug). If not, then VTK should open the file as it is and the user can perform any transformation of the data.
If I construct a scene in a z-up world, then the only way I can write it to a compliant glTF file is to rotate it all, export, and then rotate it back.
And as far as importing, I may be using the importer wrong, but since it dumps things straight into a renderer, it’s problematic to go through and find all the bits that need rotating. Although, to be frank, that’s what I’m currently doing. And it’s a bit problematic, because I don’t get one actor per node in the scene (i.e., I lose the empty root node). But that might be attributable to errors on my part in understanding the “right” way to do that.
While this issue is predominantly about the exporter ignoring assemblies, if you’re an importer expert, I’d love to take any pointers you have to offer about importing (achieving the rotation). Shall I open another question and post my current code for critique? If there’s a better way to achieve what I’m doing, I’d happily take it.