X3DInterpolatorNode : X3DChildNode {
  SFFloat      [in]     set_fraction
    range: (-Inf,Inf)
  MFFloat      [in,out] key           []
    range: (-Inf,Inf)
    change: chNone

  SFString [in,out]     interpolation            "LINEAR"
    range: ["LINEAR"|"STEP"]
    enumerated-type: TInterpolation InterpolationNames inLinear
    change: chNone
}

ColorInterpolator : X3DInterpolatorNode {
  MFColor [in,out] keyValue      []
    range: [0,1]
    change: chNone
  SFColor [out]    value_changed
}

# See https://castle-engine.io/x3d_implementation_interpolation.php
ColorSetInterpolator : X3DInterpolatorNode {
  MFColor  [in,out]  keyValue           []
    change: chNone
  MFColor  [out]     value_changed
}

CoordinateInterpolator : X3DInterpolatorNode {
  MFVec3f [in,out] keyValue      []
    range: (-Inf,Inf)
    change: chNone
  MFVec3f [out]    value_changed
}

CoordinateInterpolator2D : X3DInterpolatorNode {
  MFVec2f [in,out] keyValue      []
    range: (-Inf,Inf)
    change: chNone
  MFVec2f [out]    value_changed
}

# Note: X3D spec doesn't say this descends from X3DChildNode,
# but it is natural (where else would you put this node?)
EaseInEaseOut : X3DChildNode {
  SFFloat [in]     set_fraction
    range: (-Inf,Inf)
  MFVec2f [in,out] easeInEaseOut            []
    range: (-Inf,Inf)
    change: chNone
  MFFloat [in,out] key                      []
    range: (-Inf,Inf)
    change: chNone
  SFFloat [out]    modifiedFraction_changed
}

NormalInterpolator : X3DInterpolatorNode {
  MFVec3f [in,out] keyValue      []
    range: (-Inf,Inf)
    change: chNone
  MFVec3f [out]    value_changed
}

OrientationInterpolator : X3DInterpolatorNode {
  MFRotation [in,out] keyValue      []
    range: [-1,1] or (-Inf,Inf)
    change: chNone
  SFRotation [out]    value_changed
  SFBool     [in,out] keyValueQuaternions FALSE
    change: chNone
    doc: When @true, key values are provided as unit quaternions. By default (when @false) they have to be axis angle rotations. This allows extra optimization in case your input data is in quaternions, which is true in case of glTF. It is then most efficient to just put quternions in TOrientationInterpolatorNode.FdKeyValue and set this to @true.  Otherwise, you would 1. needlessly convert quaternion -> axisangle when reading glTF file, 2. needlessly convert axisangle -> quaternion as a first step of SLerp.
}

PositionInterpolator : X3DInterpolatorNode {
  MFVec3f [in,out] keyValue      []
    range: (-Inf,Inf)
    change: chNone
  SFVec3f [out]    value_changed
}

PositionInterpolator2D : X3DInterpolatorNode {
  MFVec2f [in,out] keyValue      []
    range: (-Inf,Inf)
    change: chNone
  SFVec2f [out]    value_changed
}

ScalarInterpolator : X3DInterpolatorNode {
  MFFloat [in,out] keyValue      []
    range: (-Inf,Inf)
    change: chNone
  SFFloat [out]    value_changed
}

SplinePositionInterpolator : X3DInterpolatorNode {
  SFBool  [in,out] closed            FALSE
    change: chNone
  MFVec3f [in,out] keyValue          []
    range: (-Inf,Inf)
    change: chNone
  MFVec3f [in,out] keyVelocity       []
    range: (-Inf,Inf)
    change: chNone
  SFBool  [in,out] normalizeVelocity FALSE
    change: chNone
  SFVec3f [out]    value_changed
}

SplinePositionInterpolator2D : X3DInterpolatorNode {
  SFBool  [in,out] closed            FALSE
    change: chNone
  MFVec2f [in,out] keyValue          []
    range: (-Inf,Inf)
    change: chNone
  MFVec2f [in,out] keyVelocity       []
    range: (-Inf,Inf)
    change: chNone
  SFBool  [in,out] normalizeVelocity FALSE
    change: chNone
  SFVec2f [out]    value_changed
}

SplineScalarInterpolator : X3DInterpolatorNode {
  SFBool  [in,out] closed            FALSE
    change: chNone
  MFFloat [in,out] keyValue          []
    range: (-Inf,Inf)
    change: chNone
  MFFloat [in,out] keyVelocity       []
    range: (-Inf,Inf)
    change: chNone
  SFBool  [in,out] normalizeVelocity FALSE
    change: chNone
  SFFloat [out]    value_changed
}

SquadOrientationInterpolator : X3DInterpolatorNode {
  MFRotation [in,out] keyValue          []
    range: (-Inf,Inf)
    change: chNone
  SFBool     [in,out] normalizeVelocity FALSE
    change: chNone
  SFRotation [out]    value_changed
}

VectorInterpolator : X3DInterpolatorNode {
  MFFloat  [in,out]  keyValue           []
    change: chNone
  MFFloat  [out]     value_changed
}
