-
Notifications
You must be signed in to change notification settings - Fork 0
SplineInterpolator nodes with glTF spline interpolation
Date: Fri, 10 Aug 2018 11:29:58 -0400
X3D and glTF spline interpolation agree well on the interpolation method but currently differ on how tangents are derived from input data. There are two significant differences: X3D uses only one input tangent, whereas glTF uses two input tangents. And X3D weights tangents in terms of a fraction, eg. unitless time, whereas glTF weights by the current interval in units of time, eg seconds. This has implications on the magnitude of the supplied tangent data, and requires a conversion.
To align X3D with glTF, a new mode field for the spline interpolator nodes is proposed which can be used for switching processing to a glTF compatible mode. The mode field's default value (say 'useVelocity') would not lead to any changes in behaviour. A value of say 'useTangents' would lead to the following changes in behaviour:
Expect and require a and b type tangents in a keyValue triplet: inTangent (ai) value (pi) outTangent (bi). Ignore the keyVelocity field. Use
p(t) = (2t3 - 3t2 + 1)p0 + (t3 - 2t2 + t)m0 + (-2t3 + 3t2)p1 + (t3 - t2)m1
t is the fractional time in the current interval ti to ti+1 where the tangents are
m0 = (ti+1 - ti)bi
m1 = (ti+1 - ti)ai+1
As an implementation note, it is important to recognize that time t is not the fraction_changed relative time used in the key field but the time in seconds since the start of the current cycle, eg. fraction_changed times cycleInterval. This is how glTF tangents are defined. It would be also possible to define ti as fractional time (eg. key) and require conversion of glTF tangents a and b during import by multiplication with the glTF animation duration (cycleInterval).
It is possible to convert old keyVelocity values to new in and outTangent values, so over time the default for the mode could become the new behaviour.
x3d: http://www.web3d.org/documents/specifications/19775-1/V3.3/index.html
fractional time is identical:
s in x3d
t in gltf
velocity/tangent:
T vector in x3d
m vector in gltf, m is input weighted by interval
x3d calculation if velocities are given: v(s) = ST H C
S =
s3 | x |
---|---|
s2 | x |
s | x |
1 | x |
H =
2 | -2 | 1 | 1 |
---|---|---|---|
-3 | 3 | -2 | -1 |
0 | 0 | 1 | 0 |
1 | 0 | 0 | 0 |
C =
vi | x |
---|---|
vi+1 | x |
T0i | x |
T1i+1 | x |
ST H C =
(2 vi- 2 vi+1 + T0i + T1i+1)s3 +
(-3 vi + 3 vi+1 -2 T0i - T1i+1)s2 +
(T0i)s +
vi =
vi(2s3 - 3s2 + 1) +
vi+1(-2s3 + 3s2) +
T0i(s3 - 2s2 + s) +
T1i+1(s3 - s2)
glTF:
p(t) = (2t3 - 3t2 + 1)p0 + (t3 - 2t2 + t)m0 + (-2t3 + 3t2)p1 + (t3 - t2)m1
The formula's for X3D and glTF are identical if
p0 = vi
p1 = vi+1
m0 = T0i
m1 = T1i+1
So the only difference is how the tangents are derived.
In glTF they are:
m0 = (tk+1 - tk)bk
m1 = (tk+1 - tk)ak+1
where a and b are provided. a is called the in-tangent and b the out-tangent.
In x3d the tangents are:
T0i = F+i Ti
T1i = F-i Ti
F-i = 2 (ti+1 - ti) / (ti+1 - ti-1)
F+i = 2 (ti - ti-1) / (ti+1 - ti-1)
if the keyVelocities Ti are provided. So here they are also weighted by time intervals but in a different way. There are two significant differences: Only one input tangent is used, Ti, whereas glTF uses two input tangents. And weight is in terms of a fraction, eg. unitless time, whereas glTF uses the current interval in units of time, eg seconds. This has implications on the magnitude of the supplied tangent data.
Is it possible to keep the x3d definition of a tangent and align with glTF by treating the keyVelocity field as in-tangent and adding a keyVelocityOut field as out-tangent ?
If the keyVelocityOut field is empty, no changes in behaviour.
If the keyVelocityOut field is populated, use its values Touti in
T0i = F+i Touti
instead of
T0i = F+i Ti
How to convert the glTF tangent data to x3d tangent data ?
m1 = T1i
(ti+1 - ti)ai = 2 Ti (ti+1 - ti) / (ti+1 - ti-1)
Ti = ai (ti+1 - ti-1) / 2 ; conversion during loading of glTF
Ti: keyVelocity derived from
ai: in-tangent glTF data
ti absolute time; fraction_changed * duration (!);
Touti : keyVelocityOut field
m0 = T0i
(ti+1 - ti)bi = 2 Touti (ti - ti-1) / (ti+1 - ti-1)
Touti = (ti+1 - ti)bi (ti+1 - ti-1)/2(ti - ti-1); conversion during loading of glTF
So, yes, this would be possible for maximum backward compatibility.
Alternatively, propose a new mode='useTangents' field for the SplineInterpolators which switches processing to directly expect the a and b type tangents in a keyValue triplet: inTangent (ai) value (vi) outTangent (bi). Variants of this alternative include new nodes (Spline2PositionInterpolator ..) or a mode field for the regular Interpolators (PositionInterpolator mode='spline').
Using above relationships, if desired old x3d keyVelocity type tangents could be converted as:
m0 = T0i
(ti+1 - ti)bi = 2 Ti (ti - ti-1) / (ti+1 - ti-1)
bi = 2 Ti (ti - ti-1) / [(ti+1 - ti-1) (ti+1 - ti)]
and
Ti = ai (ti+1 - ti-1) / 2
ai = 2 Ti / (ti+1 - ti-1)
Similar relationships could be found for the case where keyVelocity was not provided, following the spec procedures.
For mode='useTangents' the keyVelocity field would be ignored.
inTangent and outTangents are required. This has two advantages. It makes implementation simple and unambiguous. And it provides maximum flexibility on exactly what kind of cubic spline is achieved since they differ only (mostly?) in the tangent calculation. Since the tangents almost necessarily come from a editor tool, the tool will already have calculated these tangents for export.
x3dom currently uses the regular Interpolator plus mode field variant for glTF purposes.