In games we often contrain scaling operation to be uniform: X, Y and Z scales needs to be the same value.
In USD the transformation operators are:
float ScaleX
float ScaleY
float ScaleZ
float3 Scale
If we want to transport an uniform scale, we either:
need to have a convention (“In this pipeline, ScaleX can be used to represent an uniform scale in three directions“), but that makes the ScaleX ambiguous. We could add a metadata on the ScaleX attribute to make it as to be treated as an uniform scale, but that’s not ideal either.
Check in client code that the float3 scale has the same values in X, Y and Z
Would a new float TypeScaleUniform transform type be desirable in USD ?
Would a new float TypeScaleUniform transform type be desirable in USD ?
Theoretically, I think it would be handy, if only to make it easy to check if an xform stack (potentially) has any non-rigid xform elements.
But it’s also a largish change, so I’m guessing Pixar won’t want to do it without a decent amount of demand.
For a solution for right now:
need to have a convention (“In this pipeline, ScaleX can be used to represent an uniform scale in three directions“), but that makes the ScaleX ambiguous. We could add a metadata on the ScaleX attribute to make it as to be treated as an uniform scale, but that’s not ideal either.
I’d strongly advise against this. It would result in the “correct” (from a USD perspective - one that treats ScaleX as a normal nonrigid ScaleX) matrix differing from the intended matrix (where ScaleX gets swapped out for uniform scale). While your pipeline / tools may be coded to be aware of this convention, and do the correct translation, any xform code within USD itself would not be. It’s possible that you don’t use any bits of USD that rely on this, but even so, that would be fragile - there’s no guarantees that the next version of USD won’t do some matrix math behind the scenes that ends up messing up something for you.
It’s also less friendly to anybody external.
Check in client code that the float3 scale has the same values in X, Y and Z
This is the “canonical” way to do it.
In fact, if you’re even considering the option 1 (“convention that ScaleX => uniform scale”), then you’re presumably dealing with a fairly closed ecosystem, so you could swap your option 1 for a “convention that Scale3 => uniform scale” - ie, internally you always write out scales with same XYZ, and when reading you skip verification that this is true.
Of course, it only saves you 2 equality checks, so… ¯\_(ツ)_/¯
Very legit concern, @charlesfleche . I’ll note for context that the first PointInstancer schema we deployed internally prior to Open-sourcing included a float[] uniformScales attribute in addition to a float3[] scales attribute, as we believed many needs would be for uniform scaling, and in that case we’d save a bunch of storage for big datasets. But after incorporating it into our pipeline, we felt the added complexity it added for clients didn’t warrant it, so we left it out of the new schema we published.
Not saying that analysis applies here at all, but it does add complexity, e.g. in mapping an Xformable to a fixed-function component-wise DCC transform schema that does not have a uniform scale.
I would plus what @pmolodo said and suggest leveraging a UsdValidator in your pipeline, and that also provides the perfect place to deploy your ScaleX rule: if the validator includes a “Fixer”, then the Fixer can propagate the X scale to the other components.
Thanks for the UsdValidator suggestion. We haven’t taken a look at this yet, our USD pipeline is still rather closed and does not involve a lot of third-party sources, but this prompts me to read more about it.