CesiumGS/3d-tiles

Clarification for `offset` and `scale` of metadata properties

javagl opened this issue · 5 comments

Updated based on the comment below

The section that defines offset and scale shows the computation of the actual property value, based on the "raw" value, and mentions how this concept is applied to different types (e.g. vector- or array types), but some further clarification for this part - and analogously, the part that defines minimum and maximum - may be necessary.

The points that should be made clearer:

  • The offset and scale properties are only applicable when the property either has a floating-point componentType, or when normalized is set to true.
  • An implementation note should point out the possible lossiness of the conversion (beyond what is already said in the "Normalized Values" section)
  • The structure of the offset and scale, must match the type of the property, but their components are treated as floating point values.
  • The structure of minimum and maximum must match the type of the property. If the normalized flag is set to true, then their components will be floating point values. Otherwise, their components will match the componentType of the property.

Note: I had created some example computations for the EXT_structural_metadata specification that show the use of offset and scale for some example types, but the JSON-specific part is not applicable here.


Note: There are no explicit statements about overflows that may appear when computing result = offset + scale * normalize(value). The implementation note in the "Normalized Values" section mentions that some bits may be lost under certain conditions when normalized=true. An implementation note in the updated section emphasizes that the computations should be done in floating-point, and should retain as much precision as possible. Stricter requirements can hardly be stated here, considering that there may be implementations of this specification that focus on the GPU, where usually, only 32 bit floating point values are available.


The preview of the updated section can now be found in #640

For properties that are normalized or define an offset or scale, the component type of minimum and maximum is assumed to be a floating point type, and their values represent the the bounds of the property values after normalization or offset- or scale computations have been applied.

For all other properties, the component type of minimum and maximum matches the componentType of the property, and the values are the bounds of the original property values.

One thing to note here is that offset/scale might only appear in the property table, not in the class definition. Should the min/max always be floating point then?

This could make sense at the first glance. But I'll have to take a closer look at some corner cases. Remembering the values from CesiumGS/3d-tiles-samples#36 , where
9223372036854775807 became
9223372036854776000
due to the "roundtrip" through the double-world, it should be examined more carefully whether things like these might have undesired side-effects where eventually, (int64)realValue > (double)max or (int64)realValue < (double)min just due to the data type...

Edit

Specifically: I'd check if - (minus) 9223372036854775807 becomes - (minus) 9223372036854776000 then, or whether it's "rounding" in the wrong direction here...

This is partly why I don't like the term "floating-point" here since it's an encoding detail (though an important one). Maybe "decimal numeral" is more accurate?

During an internal discussion, we found an inconsistency in the specification:

  • The offset and scale had been supposed to cause the actual property value to become a floating-point value - regardless of the original componentType
  • It is possible to not have offset and scale in the property declaration, but only in its definition (for example, in a Property Table)

This means that it was possible to define a class where a certain property had the type UINT8, but in the instance of this class, the property would have had a floating-point type.

To solve this, the scale and offset properties now can only be used when the property is normalized, or when its componentType is a floating point type.

This solves ....

  • the inconsistency of the property type for a class and an instance
  • the difficulties of defining the minimum and maximum values
  • the questions about possible overflows that might otherwise result when, for example, an UINT8 property declared a scale:255

The expressiveness remains the same after this change: Arbitrary source ranges can be mapped to arbitrary target ranges, even when offset and scale are only applicable to normalized properties.

The first comment in this issue (with the suggestion for the updated section) has been updated accordingly.

Fixed in #640