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
andscale
properties are only applicable when the property either has a floating-pointcomponentType
, or whennormalized
is set totrue
. - 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
andscale
, must match thetype
of the property, but their components are treated as floating point values. - The structure of
minimum
andmaximum
must match thetype
of the property. If thenormalized
flag is set totrue
, then their components will be floating point values. Otherwise, their components will match thecomponentType
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 anoffset
orscale
, the component type ofminimum
andmaximum
is assumed to be a floating point type, and their values represent the the bounds of the property values after normalization oroffset
- orscale
computations have been applied.For all other properties, the component type of
minimum
andmaximum
matches thecomponentType
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
andscale
had been supposed to cause the actual property value to become a floating-point value - regardless of the originalcomponentType
- It is possible to not have
offset
andscale
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
andmaximum
values - the questions about possible overflows that might otherwise result when, for example, an
UINT8
property declared ascale: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.