Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Object bounds of Bike and Elephant full assets fail to appear for some viewers #32

Open
erich666 opened this issue Feb 16, 2023 · 8 comments

Comments

@erich666
Copy link
Contributor

The full assets CarbonFrameBike and ElephantWithMonochord have problems when loaded into viewers.

USDView tests follow, using USDView 0.22.5 (Windows, from the NVIDIA Omniverse distribution). The bike has this view, nothing, originally:

image

You have to mousewheel out to see the model (which gets far-clipped at a certain point):

image

Loading the same model on my iPhone, the bike briefly appears, then gets huge and basically disappears.

Elephant with Monochord is also defective in some similar way. On load in USDView:

image

Scrolling out:

image

I see similar problems in, for example, the Omniverse Create application: the "framed" view (hit the F key), where the camera is adjusted to the model's bounds, gives a massively zoomed-in view.

Note that the elephant model works fine on my iPhone, however: it frames just fine and the elephant plays an animation.

image

I asked a USD expert for their opinion. They wrote: "From what I see the issue is in the asset itself, it has extents meta-data hints on the immediate children that seen to be very small. USD will use this hint when computing the bounds for performance reasons in order to avoid scene traversal and bounds computation."

@erich666
Copy link
Contributor Author

Based on the comment "it has extents meta-data hints on the immediate children that seen to be very small", I looked at the Carbon Frame Bike model and tried editing it a bit. If I delete all "float3[] extent" lines (330 of those) and "float3[] extent.timeSamples" lines (one set of those) and load the model into UsdView 0.23.2 (NVIDIA's version), I do mostly see the model:

image

However, the model is still not contained within its bounding box. Things seem better without the extents, but the problem of the bounding box computed not matching the actual bounds of the object is not fixed. Call this the "half-right bounding box."

I looked at a few extents, such as those for the frame of the bike, Shape_2835. They seemed fine, comparing to the vertices contained within. Removing just the extent for this frame shape did not improve the bounding box - the box is still way small compared to the actual bike, as shown in the original report.

However, I then realized there is an extent further up this hierarchy: Rahmen (just under Bike_v2). Taking that extent out (and the extent.timeSamples):

float3[] extent = [(-0.0150696635, -0.0037140546, -0.011548625), (0.0034108516, 0.0030881094, 0.00058381306)]

I get the half-right bounding box shown above. And, looking at that extent, it's wrong - the frame itself (Shape_2835) has an extent:

float3[] extent = [(-0.85459006, -0.041664727, -0.6030443), (-0.2595614, 0.041581206, 0.07256365)]

You can see the frame's first value is outside the Rahmen's, as a start. So Rahmen's extent is wrong. Removing just Rahmen's extent and extent.timeSamples (which, inspecting them, also look wrong) gets us to the halfway-right bounding box.

So, as a start, remove or fix the Rahmen node's extents.

@erich666
Copy link
Contributor Author

With this knowledge in hand, I tried deleting the extent and extent.timeSamples for the def SkelRoot "Elefant" object at the top of the hierarchy. This indeed improves the bounding box - it almost includes the whole object. Note the elefant is not fully inside, nor is the Monochord instrument.

image

If I play the animation a bit (lower right Play button), the Elefant moves in such a way to be inside the bounding box for the hierarchy, but the Monochord is still outside (and the Monochord does not move during the animation):

image

However, if I select the Monochord itself in UsdView viewport (choosing it in the hierarchy gives a different result), it shows a good bounding box for that object:

image

Why the root object's bounding box (and SoC_ElephantWithMonochord's, which is identical) does not encompass the Monochord object's bounding box is the mystery. Perhaps this is a bug with UsdView itself? The only value in the Monochord's bounding box that pokes out of the root bounding box is the maximum X value: 12.175 vs. 9.322.

So my guess is that the Elefant is, in some sense, OK, in that the bounding box for it might be for its "rest pose". The Elefant's ear is outside this box, because its head starts tilted. But this does not explain the Monochord object, which does not move, sticking out of the root's bounding box.

Interestingly, if I remove all "extent" hints, the root bounding box gets smaller still:

image

My last experiment was to comment out all "matrix4d xformOp:transform" and "uniform matrix4d[]" lines in the model. This seems to give a rest pose, but now the root's bounding box is even worse:

image

If you select the Elefant, its bounding box is larger:

image

And the Monochord's object is also outside the root's bounds, as before:

image

It feels like the root's bounding box is (somehow) computed mostly based on the animation skeleton and not the mesh? I know very little about USD's animation system, so this needs someone knowledgeable about this system to continue the examination.

@erich666
Copy link
Contributor Author

To sum up the above: removing the bad extent and extent.timeSamples on Rahmen on the bike and for the def SkelRoot "Elefant" object makes the bounding boxes more reasonable. These extents are clearly wrong, so should be removed or fixed. I can imagine the timeSamples boxes are indeed meant to give the bounds at different times. Someone who understands the animation system and how to properly set these extents should fix things here.

That said, these are supposed to be hints. I would have thought that USDView would give a good bounding box for the first frame of the model, the one it displays at the start. I guess not - feature or bug of USDView?

@spiffmon
Copy link

Hi @erich666 and @hybridherbst . First, what I'd recommend as "best practice" for all geometry in a USD file, including the SkelRoot prim that indicates UsdSkel-rigged assets, for correct bounding/framing:

Every prim of a type that derives UsdGeomBoundable should have extent authored. If the prim is non-deforming, a simple default value is sufficient, otherwise a timeSample should be authored anywhere the shape changes. UsdGeomBoundable::ComputeExtentFromPlugins() can do this for you at each needed timeSample.

In its current incarnation, USD still favors "cached workflows" and wants to pull as little data across a network, and performa as little computation as possible, to fulfill a query, like computing a hierarchical bbox. Therefore it prefers authored extent properties over computations on posed-points, and framing performance on large scenes will suffer dramatically without pre-computed extents. This is exceptionally true when it comes to SkelRoot actors, because computing the extent requires not only reading all the base geometry, but applying all the LBS skinning and blend-shapes. (Noting that the SkelRoot implementation of bounds computation could be refactored and exposed in a vectorized-over-time-queries) fashion for faster authoring/caching performance - it will currently refetch and recompute all posing data on each query time).

@erich666 , I would expect, though, that if you removed all bad extent properties from the scene that you would get reasonably good bounds (if you take quick look at the implementation, you'll see it is taking some shortcuts using a "padding" heuristic to avoid actually needing to pose all the skinned meshes).

So it won't be perfect, and probably there is room for improvement. If it seems way off, please do file a bug on the USD gitHub repo, with a repro?

@erich666
Copy link
Contributor Author

erich666 commented Feb 28, 2023

Thanks, @spiffmon , this is great stuff. Note that I did remove all extent properties of any sort from both scenes and got bounding boxes that were smaller than the actual geometry. Not so bad for the Elephant with Monochord model, but pretty noticeable for the bike:
image

Is this expected behavior?

@spiffmon
Copy link

Hi @erich666 , by any chance is the bike also a Skel-based model? And if so, is the Skeleton actually "small", i.e. no bones past the handlebar assembly and rear strut? The heuristic I mentioned applies that padding around the pose skeleton, in the assumption that the skeleton is a fair approximation of the actual model. I reckon the heuristic could possibly be improved, and we could also (or DIY) use the actual full Skel posing engine to compute extents on the actual posed points. You may need to flex your usdview skills to see the Skeleton, but it can be visualized.

If the bike is not a Skel, then the only other possibility I can think of is interference from extentsHint on the model root prim - is that attribute authored?

@hybridherbst
Copy link
Contributor

Hey @spiffmon, the bike uses a mix of techniques – the overall structure is not a skeleton, but the wires on the brakes are. See https://prefrontalcortex.de/labs/model-viewer/upload/CarbonFrameBike/

I'm not sure if extentsHint has been exported (this was exported with Usd-for-Unity)

@erich666
Copy link
Contributor Author

The carbon bike fix looks reasonable to me in UsdView - great! I hope someone can fix the Elephant at some point.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants