glTF documents its internal coordinate space is y-up. This will be true for any portable glTF file. If I’m working in a domain that is z-up, I need to rotate the model from y-up to z-up.
So, here’s the circumstances:
I have a vtkRenderer
(and concomitant infrastructure). I want to import a glTF file into a renderer with some arbitrary number of vtkActor
already present. I need to rotate the model so it’s oriented to a z-up frame.
Here’s a reduction of my function:
void AddGltf(const std::string& file_name, vtkRenderer* renderer) {
vtkNew<vtkGLTFImporter> importer;
importer->SetFileName(file_name.c_str());
importer->Update();
auto* temp_renderer = importer->GetRenderer();
fmt::print("Found {} actors\n", temp_renderer->VisibleActorCount());
// All of the independent meshes/nodes in the file are put into a single
// assembly. We rotate the assembly to account for the .gltf y-up standard.
// This will ultimately become the child of another assembly that takes
// the geometry's pose.
vtkNew<vtkAssembly> file_assembly;
file_assembly->RotateX(90);
auto* actors = temp_renderer->GetActors();
actors->InitTraversal();
while (vtkActor* actor = actors->GetNextActor()) {
file_assembly->AddPart(actor);
}
// We add one more assembly node that we use pose during simulation.
vtkNew<vtkAssembly> root_assembly;
root_assembly->AddPart(file_assembly.Get());
renderer->AddActor(root_assembly);
}
I’ve attached a glTF file with the following hierarchy:
rwb_pyramid.gltf.zip (1.5 KB)
empty
|_ red_mesh
|_ blue_mesh
|_ white_mesh
Each node has a non-Identity pose w.r.t. to its parent frame.
The function prints out: Found 3 actors
(mapping to the three meshes in the glTF file).
It renders the pyramid exactly as one would expect (see image below).
Here are my questions/concerns:
- I was expecting to be able to extract a single object (the root of the hierarchy) and place it into the given
renderer
, dragging along all of its children. I was stymied in how to identify that object. - I stopped looking for the putative root object, as it seems it probably doesn’t exist. The code simply takes all the actors in the temporary renderer and stashes them on a single level into an assembly, assigning it to the target renderer. The object renders correctly, meaning that their transforms no longer depend on the hierarchy – they’ve been baked into each node.
- It seems if I did an import-export, the resulting glTF file would be appreciably different.
- Is there a better, more canonical way to achieve this end?