HAnimDisplacer : X3DGeometricPropertyNode {
  default-container-field: displacers

  MFInt32  [in,out] coordIndex    []
    range: [0,Inf) or -1
  SFString [in,out] description   ""
    change: chNone
  MFVec3f  [in,out] displacements []
  SFString [in,out] name          ""
  SFFloat  [in,out] weight        0.0
    range: (-Inf,Inf)
}

HAnimHumanoid : X3DChildNode, X3DBoundedObject {
  SFVec3f    [in,out] center           0 0 0
    range: (-Inf,Inf)
    change: chTransform
  SFString   [in,out] description      ""
    change: chNone
  MFString   [in,out] info             []
  MFNode     [in,out] joints           []
    range: HAnimJoint
  MFVec3f    [in,out] jointBindingPositions []
  MFRotation [in,out] jointBindingRotations []
  MFVec3f    [in,out] jointBindingScales    []
  SFInt32    [in,out] loa              -1
  MFNode     [in,out] motions               []
    range: HAnimMotion
  MFBool     [in,out] motionsEnabled        []
  SFString   [in,out] name             ""
  SFRotation [in,out] rotation         0 0 1 0
    range: (-Inf,Inf)|[-1,1]
    change: chTransform
  SFVec3f    [in,out] scale            1 1 1
    range: (0,Inf)
    change: chTransform
  SFRotation [in,out] scaleOrientation 0 0 1 0
    range: (-Inf,Inf)|[-1,1]
    change: chTransform
  MFNode     [in,out] segments         []
    range: HAnimSegment
  MFNode     [in,out] sites            []
    range: HAnimSite
  SFString   [in,out] skeletalConfiguration "BASIC"
  MFNode     [in,out] skeleton         []
    range: HAnimJoint, HAnimSite
  MFNode     [in,out] skin             []
    range: X3DChildNode
  SFNode     [in,out] skinBindingCoord      NULL
    range: X3DCoordinateNode
  SFNode     [in,out] skinBindingNormal     NULL
    range: X3DNormalNode
  SFNode     [in,out] skinCoord        NULL
    range: X3DCoordinateNode
  SFNode     [in,out] skinNormal       NULL
    range: X3DNormalNode
  SFVec3f    [in,out] translation      0 0 0
    range: (-Inf,Inf)
    change: chTransform
  SFString   [in,out] version          ""
  MFNode     [in,out] viewpoints       []
    # X3D specificaion indicates that HAnimSite is allowed here,
    # but textual description in HAnim specification indicates that
    # it's an error: viewpoints should be allowed here.
    # Confirmed by testing models from
    # http://www.web3d.org/x3d/content/examples/Basic/HumanoidAnimation/
    range: HAnimSite, X3DViewpointNode, ViewpointGroup
  SFVec3f    []       bboxCenter       0 0 0
    range: (-Inf,Inf)
  SFVec3f    []       bboxSize         -1 -1 -1
    range: [0,Inf) or -1 -1 -1
}

HAnimJoint : X3DGroupingNode {
  SFVec3f    [in,out] center           0 0 0
    range: (-Inf,Inf)
    change: chTransform
  SFString   [in,out] description      ""
    change: chNone
  MFNode     [in,out] displacers       []
    range: HAnimDisplacer
  SFRotation [in,out] limitOrientation 0 0 1 0
    range: (-Inf,Inf)|[-1,1]
  MFFloat    [in,out] llimit           []
    range: (-Inf,Inf)
  SFString   [in,out] name             ""
  SFRotation [in,out] rotation         0 0 1 0
    range: (-Inf,Inf)|[-1,1]
    change: chTransform
  SFVec3f    [in,out] scale            1 1 1
    range: (0,Inf)
    change: chTransform
  SFRotation [in,out] scaleOrientation 0 0 1 0
    range: (-Inf,Inf)|[-1,1]
    change: chTransform
  MFInt32    [in,out] skinCoordIndex   []
  MFFloat    [in,out] skinCoordWeight  []
  MFFloat    [in,out] stiffness        [0, 0, 0]
    range: [0,1]
  SFVec3f    [in,out] translation      0 0 0
    range: (-Inf,Inf)
    change: chTransform
  MFFloat    [in,out] ulimit           []
    range: (-Inf,Inf)
}

# Note: default-container-field for HAnimMotion
# (not specified, but inherited from X3DChildNode) is ignored
# when reading / writing X3D. We use instead
# THAnimMotionNode.DefaultContainerFieldInContext
# to account for the fact that containerField depends on parent,
# see https://github.com/castle-engine/castle-model-viewer/issues/69 .

HAnimMotion : X3DChildNode {
  SFBool   [in]     next
  SFBool   [in]     previous
  SFString [in,out] channels         ""
  MFBool   [in,out] channelsEnabled  []
  SFString [in,out] description      ""
  SFBool   [in,out] enabled          TRUE
  SFInt32  [in,out] endFrame         0
    range: [0,Inf)
  SFTime   [in,out] frameDuration    0.1
    range: (0,Inf)
  SFInt32  [in,out] frameIncrement   1
    range: (-Inf,Inf)
  SFInt32  [in,out] frameIndex       0
    range: [0,Inf)
  SFString [in,out] joints           ""
  SFInt32  [in,out] loa              -1
    range: [-1,4]
  SFBool   [in,out] loop             FALSE
  SFString [in,out] name             ""
  SFInt32  [in,out] startFrame       0
    range: [0,Inf)
  MFFloat  [in,out] values           []
    range: (-Inf,Inf)
  SFTime   [out]    cycleTime
  SFTime   [out]    elapsedTime
    range: (0,Inf)
  SFInt32  [out]    frameCount
    range: [0,Inf)
}

HAnimSegment : X3DGroupingNode {
  SFVec3f  [in,out] centerOfMass     0 0 0
    range: (-Inf,Inf)
  SFNode   [in,out] coord            NULL
    range: X3DCoordinateNode
  SFString [in,out] description      ""
    change: chNone
  MFNode   [in,out] displacers       []
    range: HAnimDisplacer
  SFFloat  [in,out] mass             0
    range: [0,Inf)
  MFFloat  [in,out] momentsOfInertia [0, 0, 0, 0, 0, 0, 0, 0, 0]
    range: [0,Inf)
  SFString [in,out] name             ""

  # Segment.rotation, scale, translation are extensions of Blaxxun
  # avatars, at least that's what
  # http://tecfa.unige.ch/vrml/objects/avatars/blaxxun/ suggests.
  # They are not conforming to HAnim 1.0 or 200x specification.
  SFRotation [in,out] rotation         0 0 1 0
    range: (-Inf,Inf)|[-1,1]
    change: chTransform
  SFVec3f    [in,out] scale            1 1 1
    range: (0,Inf)
    change: chTransform
  SFVec3f    [in,out] translation      0 0 0
    range: (-Inf,Inf)|[-1,1]
    change: chTransform
}

HAnimSite : X3DGroupingNode {
  SFVec3f    [in,out] center           0 0 0
    range: (-Inf,Inf)
    change: chTransform
  SFString   [in,out] description      ""
    change: chNone
  SFString   [in,out] name             ""
  SFRotation [in,out] rotation         0 0 1 0
    range: (-Inf,Inf)|[-1,1]
    change: chTransform
  SFVec3f    [in,out] scale            1 1 1
    range: (0,Inf)
    change: chTransform
  SFRotation [in,out] scaleOrientation 0 0 1 0
    range: (-Inf,Inf)|[-1,1]
    change: chTransform
  SFVec3f    [in,out] translation      0 0 0
    range: (-Inf,Inf)|[-1,1]
    change: chTransform
}
